Write yourself a simple Thunder download support breakpoint Continuation

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.