Threads can be understood as downloaded channels, a thread is a file download channel, multithreading is also open several download channels at the same time. When the server provides the download service, the use of the download is shared bandwidth, in the case of the same priority, the total server will be the total download thread distribution. It is not difficult to understand, if you line multithreading, then the faster the download.
The popular download software is multi-threaded and supports pausing the download at the beginning without starting the download from scratch.
The following steps are implemented for both functions:
(1) When connecting to the download resource file, first determine the resource file size, synchronously create a locally sized temporary file to store the downloaded data.
(2) Determine the file size that each thread needs to download according to the number of threads
(3) Depending on the file size and number of threads downloaded per thread, determine the start download location and end download location for each thread
(4) In order to implement the breakpoint download function, we need to mark the location of each thread's real-time download, so that we can continue to download the progress before the next start.
Open 3 Threads Download view (default download directory is Java-governed project):
The overall implementation of the code is as follows (optimization of space is also very large oh, we do not just look at the finished it)
1 ImportJava.io.BufferedReader;2 ImportJava.io.File;3 ImportJava.io.FileInputStream;4 ImportJava.io.InputStream;5 ImportJava.io.InputStreamReader;6 ImportJava.io.RandomAccessFile;7 Importjava.net.HttpURLConnection;8 ImportJava.net.URL;9 Public classDownLoad {Ten //declaring the download path "Red Alert 2" One Public Static FinalString PATH = "Http://soft3.xzstatic.com/2015/10/hsjj2ghgzh.rar"; A Public Static intThreadCount = 0;//declaring the number of threads - Public Static voidMain (string[] args) { - Try { theURL url =NewURL (PATH); - //Get Connections -HttpURLConnection conn =(HttpURLConnection) url.openconnection (); - //by getting the connection definition file name +string[] str = path.split ("/"); -String FileName = str[5]; + //get the download file size A intFilelength =conn.getcontentlength (); at System.out.println (fileName); - //create a randomly writable file locally that is consistent with the size of the server -Randomaccessfile RAF =NewRandomaccessfile (FileName, "RWD"); -System.out.println (filelength);//for testing - raf.setlength (filelength); - //Number of custom threads inThreadCount = 3; - //calculate the size of each thread's downloaded data to intBlockSize = filelength/ThreadCount; + //start thread Download - for(intThreadId = 1; ThreadId <= ThreadCount; threadid++) { the //The core code that defines where each thread starts and ends download * intstartpos = (threadId-1) * blockSize;//where to start the download $ intEndpos = (THREADID * blockSize)-1;//End download location (not including last piece)Panax Notoginseng if(ThreadCount = =threadId) { -Endpos =filelength; the } + NewThread (NewDownloadthread (ThreadId, Startpos, Endpos, PATH)) A . Start (); the } +}Catch(Exception e) { - e.printstacktrace (); $ } $ } - - //implementing the Download thread the Static classDownloadthreadImplementsRunnable { - Private intthreadId;Wuyi Private intstartpos; the Private intEndpos; - PrivateString Path; Wu PublicDownloadthread (intThreadId,intStartpos,intEndpos, - String Path) { About Super(); $ This. ThreadId =threadId; - This. startpos =startpos; - This. Endpos =Endpos; - This. Path =path; A } + Public voidrun () { the Try { -URL url =NewURL (path); $string[] str = path.split ("/"); theString FileName = str[5]; theHttpURLConnection conn =(httpurlconnection) URL the . OpenConnection (); the //How to set the URL request (Reference API) -Conn.setrequestmethod ("GET"); in //set the timeout value for 500 milliseconds theConn.setreadtimeout (5000); theFile File =NewFile (threadId + ". txt"); About if(File.exists () && file.length () > 0) { theBufferedReader br =NewBufferedReader ( the NewInputStreamReader (Newfileinputstream (file)); theString Savestartpos =br.readline (); + if(Savestartpos! =NULL&& savestartpos.length () > 0) { -Startpos =Integer.parseint (savestartpos); the }Bayi } the //note the format within the double quotation marks, and cannot contain spaces (and other characters), otherwise the report 416 theConn.setrequestproperty ("Range", "bytes=" + startpos + "-" -+endpos); -Randomaccessfile RAF =NewRandomaccessfile (FileName, "RWD");//a random write file that stores downloaded files theRaf.seek (startpos);//set where to start the download theSYSTEM.OUT.PRINTLN ("thread" + threadId + ":" + startpos + "~" the+endpos); theInputStream is =Conn.getinputstream (); - byte[] B =New byte[1024 * 1024 * 10]; the intLen =-1; the intNewpos =startpos; the while(len = Is.read (b))! =-1) {94Randomaccessfile rr =NewRandomaccessfile (file, "RWD");//files that store downloaded tags theRaf.write (b, 0, Len); the //Save the download tag to the specified document theString savapoint = string.valueof (Newpos + =len);98 Rr.write (Savapoint.getbytes ()); About rr.close (); - }101 is.close ();102 raf.close ();103System.out.println ("Download Complete");104}Catch(Exception e) { the e.printstacktrace ();106 }107 }108 }109}
Precautions:
(1) Understand the calculation method for the start and end location of each thread download (does not contain the last thread, starting from 0)
Start position = (Number of threads-1) * File length (size) to download per thread
End position = (number of threads * File size downloaded per thread)-1
(2) The last thread assigned the download start location is the end position of the previous thread and the end position is the file length.
So the last thread downloaded the file length is generally not the same as the front thread
(3) This demo download path defaults to the directory where the Java project resides, and the directory cannot contain files with the same name as the downloaded file, otherwise the program will report 416 network request errors.
(4) A mistake I made in my personal implementation conn.setrequestproperty ("Range", "bytes=" + startpos+ "-" +endpos); Be sure to note that the quotation marks do not have to have extra space and other characters, I am in the quotation marks more than a space, but the error location has been InputStream error, find the wrong find very painful
Java implementation Multi-threaded breakpoint download (can be paused during download)