Package com. sli. thread;
Import java. io. FileNotFoundException;
Import java. io. IOException;
Import java. io. InputStream;
Import java. io. RandomAccessFile;
Import java.net. HttpURLConnection;
Import java.net. MalformedURLException;
Import java.net. URL;
Import java. util. Date;
Public class Main extends Thread {
String urlt = "";
Int startl;
Int end;
String fileName;
RandomAccessFile osf;
Public Main (int I, String url, String fileName, int start, int end ){
This. setName ("thread" + I); // subthread name
This. urlt = url ;//
This. fileName = fileName;
This. startl = start; // The starting byte for sub-thread reading/writing
This. end = end; // The length of the end bytes written by the subthread.
}
Public void run (){
Try {
Osf = new RandomAccessFile (fileName, "rw ");
URL url = new URL (urlt );
HttpURLConnection http2 = (HttpURLConnection) url. openConnection ();
Http2.setRequestProperty ("User-Agent", "NetFox ");
/*
* Key code for resumable data transfer and multi-thread download: sets the breakpoint http2.setRequestProperty ("RANGE ",
* "Bytes =" + startl + "-"); // sets the breakpoint location and requests the server from which bytes of the file is read.
* Osf. seek (startl); // set the byte from which the local file is written. If it is a single thread, first determine whether the downloaded file already exists.
* And fileName = "C: \ eclipse.zip" in DownloadFile. java ";
* If resumable upload exists, the resumable upload starts in the same way as multithreading:
* Because resumable data transfer starts from the bytes interrupted during the previous transmission, you must first obtain the last interrupted location, which is not only the file length (for a single thread) f. length ()
* Set the RANGE attribute of the HTTP Request Header, which informs the server from which the file is read.
* Set the start byte for writing local files, and continue writing from the last transmission breakpoint (resumable upload) osf. seek (offset)
* This method is used to write data from the last byte of offset.
* Note: multithreading does not use the file length as the start byte for writing files. configuration files must be recorded for the last read/write location. This method is used for thunder download.
*/
Http2.setRequestProperty ("RANGE", "bytes =" + startl + "-"); // sets the breakpoint location and requests the server from which bytes of the file is read.
Osf. seek (startl); // you can specify the byte from which the local file is written.
InputStream input = http2.getInputStream ();
Byte B [] = new byte [1024]; // sets the buffer pool, read-only 1024 bytes each time
Date d = new Date (); // The download start time of the subthread.
Int l; // calculate the length of the file read and written by the subthread. When the length is greater than the average download length of each subthread, the thread is terminated.
Int I;
L = 0;
System. out. println (this. getName () + "to download... ");
While (I = input. read (B, 0, 1024 ))! =-1 & l <end) {// The Length Control Error of the thread download byte is smaller than the buffer pool size. In this example, the buffer pool is 1024 bytes.
Osf. write (B, 0, I );
B = new byte [1024]; // re-assign values to avoid re-reading the old content
L + = I;
}
Date d2 = new Date (); // The download end time of the subthread.
System. out. println (this. getName () + "thread time consumption :"
+ (D2.getTime ()-d. getTime ()/1000 + "seconds, total download:" + l
+ "Byte"); // sub-thread download time (seconds)
} Catch (FileNotFoundException e1 ){
// TODO Auto-generated catch block
E1.printStackTrace ();
} Catch (MalformedURLException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
}
/*
* Test class
*/
Package com. sli. thread;
Import java. io. File;
Import java. io. IOException;
Import java. io. RandomAccessFile;
Import java.net. HttpURLConnection;
Import java.net. URL;
Public class DownLoad {
/**
* @ Param args
*/
Static int len; // The average length of the downloaded file by the thread
Static int bn; // The number of bytes written to the file by each thread
Static int tn; // Number of threads
Static String urlt ;//
Static String fileName;
Static RandomAccessFile osf; // File Operations
Public static void main (String [] args ){
Try {
Urlt = "fileName =" C :\\"
+ Urlt. split ("//") [1]. split ("/") [urlt. split ("//") [1]
. Split ("/"). length-1];
System. out. println (fileName );
URL url = new URL (urlt );
HttpURLConnection http = (HttpURLConnection) url. openConnection ();
/**
* Set 5 threads to download a file tn = 5. determine the average length of the file to be downloaded by each thread:
*/
System. out. println ("file size:" + http. getContentLength ());
Tn = 10;
Len = http. getContentLength ()/tn; // calculate the average length of each thread to be downloaded, and add the remainder to the last thread,
File f = new File (fileName );
If (f. exists ()){
F. delete ();
Osf = new RandomAccessFile (f, "rw ");
Osf. seek (http. getContentLength ()-1 );
Osf. write (0 );
} Else {
Osf = new RandomAccessFile (f, "rw ");
Osf. seek (http. getContentLength ()-1 );
Osf. write (0 );
}
System. out. println ("temp File length:" + f. length ());
Thread t; // download the sub-Thread,
For (int j = 0; j <tn; j ++ ){
If (j = tn-1) {// if the last thread is added with the remainder Length Byte
Bn = len + (http. getContentLength () % tn );
} Else {
Bn = len;
}
System. out
. Println ("t" + j + "thread download length:" + bn + "Start byte:" + len * j );
T = new Main (j, urlt, fileName, len * j, bn
);
T. start ();
}
} Catch (IOException e ){
E. printStackTrace ();
}
}
}
Author: Luo Shengli