When I learned the network thread, I have to imitate the Thunder download wrote a downloader, support the breakpoint continued to pass
I'm using the SWT plugin interface.
Interface
Package Com.yc.xunlei;import Java.io.file;import Java.io.filenotfoundexception;import java.io.FileOutputStream; Import Java.io.ioexception;import java.io.objectoutputstream;import java.util.arraylist;import java.util.HashMap; Import Java.util.list;import Java.util.map;import Org.eclipse.swt.widgets.display;import Org.eclipse.swt.widgets.shell;import Org.eclipse.swt.widgets.label;import Org.eclipse.swt.swt;import Org.eclipse.swt.widgets.messagebox;import Org.eclipse.swt.widgets.text;import Org.eclipse.swt.widgets.Button; Import Org.eclipse.swt.widgets.progressbar;import Org.eclipse.swt.widgets.combo;import Org.eclipse.swt.events.selectionadapter;import Org.eclipse.swt.events.selectionevent;public class Xunlei { Protected Shell shell;private Text txt;private Combo combo;private long sum;private ProgressBar progressbar;private File D Ownloadfile;private Text text;private map<string, list<threadinfo>> threadinfos = new HashMap<String, List<threadinfo>> ();p rivate Label LABel_2;private String key;downloadutils dlu;/** * Launch the application. * * @param args */public static void main (string[] args) {try {xunlei window = new Xunlei (); window.open ();} catch (Except Ion e) {e.printstacktrace ();}} /** * Open the window. */public void Open () {Display display = Display.getdefault (); createcontents (); Shell.open (); Shell.layout (); while (! Shell.isdisposed ()) {if (!display.readanddispatch ()) {display.sleep ();}}} /** * Create contents of the window. */protected void createcontents () {shell = new shell (); Shell.setsize (610, 468); Shell.settext ("\u8fc5\u96f7\u4e0b\ U8f7d "); Label Lblurl = new label (Shell, SWT. NONE); Lblurl.setbounds (+, +, +); Lblurl.settext ("URL:"); txt = new Text (Shell, SWT. BORDER); Txt.settext ("Http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ_v7.3.15056.0_setup.1435111953.exe"); Txt.setbounds (72, 33, 520, 18); Button button = New button (Shell, SWT. NONE); Button.setbounds (127, 201, Button.settext ("\u4e0b\u8f7d"); Button button_1 = New button (ShelL, SWT. NONE); Button_1.setbounds (236, 201, N), Button_1.settext ("\u6682\u505c");p Rogressbar = new ProgressBar (Shell, SWT. NONE);p Rogressbar.setbounds (72, 245, 461, 17); Label label = new label (Shell, SWT. NONE); Label.setbounds (Label.settext); ("\u7ebf\u7a0b\u6570:"); combo = new Combo (shell, SWT. NONE); Combo.setitems (new string[] {"5", "6", "7", "8", "9", "Ten"}); Combo.setbounds (a); Combo.select (0); Label Label_1 = new label (Shell, SWT. NONE); Label_1.setbounds (141, Wu), Label_1.settext ("\u4fdd\u5b58\u4f4d\u7f6e:"); text = new text (Shell, SWT. Text.setbounds (141, 296, BORDER), Text.settext (System.getproperty ("User.home")); label_2 = new label (Shell, SWT . NONE); Label_2.setbounds (127, 281, 342, 31);//Pause Method Button_1.addselectionlistener (new Selectionadapter () {@ overridepublic void widgetselected (Selectionevent e) {if (dlu! = null) {dlu.stop ();}}); * * A. Create a file to download to a local disk B. Set the total length of the ProgressBar on the interface c. Start the download again * d. Modify SYSTEM.OUT.PRINTLN ("already downloaded:" + sum+ "bytes"); for progressBar setting */button.addselectionlistener (new Selectionadapter () {@Overridepublic void widgetselected (Selectionevent e) { sum = 0; Each time the point Ji starts, the sum is assigned an initial value of 0String urlstring = Txt.gettext (). Trim (); int threadsize = Integer.parseint (Combo.gettext ()); String Savepath = Text.gettext (); try {dlu = new Downloadutils (threadsize, urlstring, savepath);d ownloadfile = Dlu.getdown LoadFile (); key = Threadsize + "_" + URLString + "_" + Downloadfile.getabsolutepath ();// Sets the total length of the ProgressBar on the Interface Progressbar.setmaximum ((int) downloadfile.length ()); Long allthreaddownloadedsize = Dlu.getallthreaddownloadedsize (key); Label_2.settext ("Total length:" + (int) downloadfile.length () + "/Downloaded Length" + allthreaddownloadedsize); sum + = allthreaddownloadedsize; Dlu.download (DownLoadFile, Urlstring,threadsize, New Onsizechangelistener () {public void Onsizechange (long downloadsize) {sum + = Downloadsize;display.getdefault (). Asyncexec (New Runnable () {@Overridepublic void run () { progressbar.setselection (int) sum); Label_2.settext ("Total length:" + (int) DOWNLOADFIle.length () + "/downloaded Length" + sum);}); if (sum >= downloadfile.length ()) {dlu.stop ();D Isplay.getdefault (). Asyncexec (New Runnable () {@Overridepublic void Run () {MessageBox MB = new MessageBox (shell, swt.no), Mb.settext ("Download Complete"), Mb.setmessage ("OK"); Mb.open ();}});}});} catch (IOException E1) {e1.printstacktrace ();}}});}}
Entity class Bean (Threadinfo)
Package Com.yc.xunlei;import Java.io.serializable;public class Threadinfo implements Serializable {private static final Long serialversionuid = -8664947024042932015l;private int threadid;private long downloadsize;public int getThreadId () { return threadId;} public void Setthreadid (int threadId) {this.threadid = threadId;} Public long Getdownloadsize () {return downloadsize;} public void Setdownloadsize (long downloadsize) {this.downloadsize = downloadsize;} Public threadinfo (int threadId, long downloadsize) {super (); this.threadid = Threadid;this.downloadsize = downloadsize;} Public Threadinfo () {super ();} @Overridepublic String toString () {return threadId + "\ T" + downloadsize;}}
Callback interface. The amount of data that is used to notify the main thread to download ...
Package com.yc.xunlei;/** * Callback interface. Used to notify the main thread of the amount of data downloaded ... * @author Administrator * */public interface Onsizechangelistener {public void Onsizechange ( long do Wnloadsize );}
Download task Class Class
Package Com.yc.xunlei;import Java.io.file;import Java.io.inputstream;import java.io.randomaccessfile;import Java.net.httpurlconnection;import Java.net.url;public class Downloadtask implements Runnable {private File Downloadfile;private String urlstring;private long startposition;private long endposition;private int threadId;private Onsizechangelistener Onsizechangelistener;p rivate boolean flag=true;private long Downloadedsize=0;private long Downloadsizeperthread;public long Getdownloadedsize () {return downloadedsize;} public int GetThreadId () {return threadId;} public void Stop () {this.flag=false;try {this.finalize ();} catch (Throwable e) {e.printstacktrace ()}} Public Downloadtask (File downLoadFile, String urlstring,long startposition, long endposition, int threadId, Onsizechange Listener Onsizechangelistener, Long downloadsizeperthread) {this.downloadfile = Downloadfile;this.urlstring = Urlstring;this.startposition = Startposition;this.endposition = Endposition;this.threadid = THREadid;this.onsizechangelistener= onsizechangelistener; this.downloadsizeperthread=downloadsizeperthread;} public void Run () {downloadedsize= startposition-threadid*downloadsizeperthread;try {URL url = new URL (urlstring); H Ttpurlconnection con = (httpurlconnection) url.openconnection (); Con.setrequestmethod ("GET"); Request Header Con.setconnecttimeout (5 * 1000); The time the request expires Con.setrequestproperty ("Connection", "keep-alive");//TODO: Issue The Agreement, specify Rangecon.setrequestproperty ("Range", " Bytes= "+ startposition +"-"+ endposition); Randomaccessfile RAF = new Randomaccessfile (downLoadFile, "RW");//Todo:raf cannot write from No. 0 byte, but must write from startposition location, the problem is, How do I control the RAF writing from a specified location? Raf.seek (startposition); InputStream IIS = Con.getinputstream (); byte[] bs = new Byte[1024];int length =- 1;while (length = Iis.read (BS, 0, bs.length))! =-1) {raf.write (BS, 0, length); if (This.onsizechangelistener!=null) {on Sizechangelistener.onsizechange (length);} this.downloadedsize+= length;//scalar, used to control the thread's pause if (!flag) {break;}} Iis.close (); cOn.disconnect (); Raf.close (); System.out.println (threadId + "line download complete, range" + StartPosition + "to" + Endposition);} catch (Exception e) {e.printstacktrace ();}}}
Download Util class
Package Com.yc.xunlei;import Java.io.file;import Java.io.fileinputstream;import java.io.FileNotFoundException; Import Java.io.fileoutputstream;import Java.io.ioexception;import Java.io.objectinputstream;import Java.io.objectoutputstream;import Java.io.randomaccessfile;import Java.net.httpurlconnection;import Java.net.malformedurlexception;import Java.net.url;import Java.util.arraylist;import Java.util.HashMap;import Java.util.list;import Java.util.map;public class Downloadutils {private list<downloadtask> downLoadTasks = new Arraylist<downloadtask> ();p rivate long allthreaddownloadedsize;private String key;private Map<String, List <ThreadInfo>> map;private int threadsize;private string Urlstring;private string Savepath;private File Downloadfile;private list<thread> threads=new arraylist<thread> ();p ublic File getDownLoadFile () {return This.downloadfile;} Public downloadutils (int threadsize, String urlstring, String savepath) throws IOException {This.threadSize = threadsize;this.urlstring = Urlstring;this.savepath = Savepath;key = Threadsize + "_" + URLString + "_" + SavePath + file.separator+ Getdownloadfilename (urlstring);d ownloadfile = Createdownloadfile (urlstring, savePath); map= Getdownloadedthreadinfomapfromtmpfile (); SYSTEM.OUT.PRINTLN ("Data read:" + map); if (map==null) {map=new hashmap< String, list<threadinfo>> ()}} Public long getallthreaddownloadedsize (String key) {allthreaddownloadedsize = 0;if (map! = null && map.size () > 0) {list<threadinfo> List = Map.get (key); for (Threadinfo ti:list) {allthreaddownloadedsize + = Ti.getdownloadsize ( );}} return allthreaddownloadedsize;} public void Stop () {if (downloadtasks! = null && downloadtasks.size () > 0) {for (int i=0;i<threads.size (); i+ +) {downloadtasks.get (i). Stop (); Thread T=threads.get (i); t=null;}} if (Isdownloadfinish ()) {map.remove (key);} Recorddownloadthreadinfo ();} private void Recorddownloadthreadinfo () {ObjectOutputStream Oos = null;try {list< threadinfo> list = new arraylist<threadinfo> (); for (Downloadtask dlt:downloadtasks) {//Add an attribute to Downloadtask Indicates the amount of data downloaded by this thread, accumulated//when paused, where the GetXXX method is called to get the amount of empty online download.//Operation disk record Threadinfo Ti = new Threadinfo (); Ti.setthreadid ( Dlt.getthreadid ()); Ti.setdownloadsize (Dlt.getdownloadedsize ()); List.add (TI);} Map.put (key, list); SYSTEM.OUT.PRINTLN ("Saved data:" +map); FileOutputStream fos = new FileOutputStream (New File (System.getproperty ("User.home"), "data.tmp")); Oos = new ObjectOutputStream (FOS); Oos.writeobject (map); Oos.flush ();} catch (Exception E1) {e1.printstacktrace ();} finally {try {if (Oos! = null) {Oos.close ();}} catch (IOException E1) {E1.pri Ntstacktrace ();}}} Private Boolean Isdownloadfinish () {//calculates the total length of the current download long downsize = 0;for (Downloadtask dlt:downloadtasks) {downsize + = DLT . Getdownloadedsize ();} Total file length Long totallength = This.downLoadFile.length (), if (downsize >= totallength) {return true;} else {return false;} }/** * Multi-threaded DOWNLOAD Implementation * * @param downLoadFile * @param urlstring * @param Threadsize * @throws ioexception */public list<downloadtask> downLoad (File downLoadFile, String urlstring,int thre Adsize, Onsizechangelistener Onsizechangelistener) throws IOException {long startposition = 0;//When the starting position of the front thread long endposition = 0; The end of the current thread//Gets the length of each thread to be downloaded long downloadsizeperthread = Getdownloadsizeperthread (Downloadfile.length (), threadsize);// Todo:1. Stitching the Map key 2. To the disk to find whether there is a map,map in this key,//3. If any, the value 4 is removed. Loop to calculate this starting position key = Threadsize + "_" + URLString + "_" + Downloadfile.getabsolutepath (); map<string, list<threadinfo>> Threadinfos = Getdownloadedthreadinfomapfromtmpfile (); list<threadinfo> list = new arraylist<threadinfo> (); if (Threadinfos! = null) {list = Threadinfos.get (key);} for (int i = 0; i < threadsize; i++) {if (List.size () >0 && list.get (i) = null) {//start position startposition = i * Downloadsizeperthread+ List.get (i). Getdownloadsize () Allthreaddownloadedsize + = List.get (i). GetDownLoadSize ();} else {//start position startposition = i * DownLoadSIzeperthread;} End Position Endposition = (i + 1) * downloadsizeperthread-1;//TODO: This place must get all instances of the downloadtask, return to the main interface, and then call//Downloadtask A method to set the scalar. Downloadtasks.add (New Downloadtask (DownLoadFile, urlstring,startposition, endposition, I, Onsizechangelistener, Downloadsizeperthread));} if (Allthreaddownloadedsize < Downloadfile.length ()) {for (int i = 0; i < threadsize, i++) {thread t=new thread (down Loadtasks.get (i)); Threads.add (t); T.start ();}} return downloadtasks;} /** * Read information on downloaded threads stored in temporary files * * @return */private map<string, list<threadinfo>> Getdownloadedthreadinfomapfromtmpfile () {map<string, list<threadinfo>> ThreadInfos = Null;O Bjectinputstream ois = null; FileInputStream fis = null;try {file F = new File (System.getproperty ("User.home"), "data.tmp"), if (!f.exists ()) {return nu ll;} FIS = new FileInputStream (f); ois = new ObjectInputStream (FIS); Threadinfos = (map<string, list<threadinfo>>) Ois.readobject ();} catch (Exception e) {E.printstacktraCE ();} Finally {try {if (ois! = null) Ois.close ();} catch (IOException e) {e.printstacktrace ()} try {if (FIS! = null) Fis.close ();} catch (IOException e) {e.printstacktrace ()}} return Threadinfos;} /** * Calculates the length of each thread to be downloaded * * @param filelength * @param threadsize * @return */public long getdownloadsizeperthread (Long Filele ngth, int threadsize) {Long downloadsizeperthread = 0;downloadsizeperthread = filelength% Threadsize = = 0? filelength/t Hreadsize:filelength/threadsize + 1;return Downloadsizeperthread;} /** * Download the file under the specified urlstring to the savepath path * * @param urlstring * @param savepath * @return saved File Object * @throws IOException */p Ublic file Createdownloadfile (String urlstring, String savepath) throws IOException {//1. Remove the length of files to download, use "Head" request header long Len Gth = Getdownloadfilelength (urlstring);//2. Remove the filename from urlstring string filename = Getdownloadfilename (urlstring);//3. Create file to Moren path or specify path under File DownLoadFile = CreateFile (Savepath, fileName, length); return downLoadFile;} /** * Remove the length of the file to be downloaded * * @param urlSTring *: The address of the file to be downloaded * @return length: Length byte length of file * @throws IOException */public long Getdownloadfilelength (strin G urlstring) throws IOException {Long length = -1;//1. Fetch the file length URL url = new URL (urlstring) to download; HttpURLConnection con = (httpurlconnection) url.openconnection (); Con.setrequestmethod ("HEAD"); Request Header Con.setconnecttimeout (5 * 1000); The time the request expires con.connect (); length = Con.getcontentlength (); return length;} /** * Gets the file name to download according to the URL * * @param urlstring * @return The file name to download * @throws malformedurlexception * @throws Malformedurlexcepti On */public string Getdownloadfilename (String urlstring) throws Malformedurlexception {if (urlstring = = NULL | | ". Equals (URLString)) {throw new IllegalArgumentException (" file name cannot be empty ");} URL url = new URL (urlstring); String file = Url.getfile (); String filename = file.substring (File.lastindexof ("/") + 1); return fileName;} /** * According to the directory name, file name, length, create a file to the specified location * * @param directory *: null "" Fffff:\ * @param fileName * @param length * @r Eturn created File Object * @throWS IOException */public File createFile (String directory, string fileName, long length) throws IOException {string Directo Rypath = null;if (Directory! = null &&! "). Equals (directory) && new File (directory). Exists ()) {directorypath = Directory;} else {directorypath = System.getproperty ("User.home");} if (FileName = = NULL | | "". Equals (filename) {throw new IllegalArgumentException ("file name does not exist");} if (length <= 0) {throw new IllegalArgumentException ("File size cannot be less than 0 bytes");} File F = new file (DirectoryPath, fileName);//TODO: To determine if the file exists, none is created, there is, there are two cases: 1. The download is complete, 2. A breakpoint must be resumed. if (f.exists ()) {return F;} Randomaccessfile RAF = new Randomaccessfile (f, "RW"); raf.setlength (length); return f;}}
Learn the network thread, write a program yourself, to deepen understanding
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Write yourself a simple Thunder download support breakpoint Continuation