package cn.me.test;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
*Multi-threaded download
*1: Use RandomAccessFile to write data at any location.
*2: The amount of data downloaded by the first thread needs to be calculated and can be distributed evenly. If it is not average enough,
* Then the last thread directly processes relatively small data
*3: Files of the same size must be prepared before downloading and obtained through the file header
*/
public class MultiThreadDownload {
public static void main(String[] args) throws Exception {
//1: Declare the file name and download address
String fileName = "aa.rar";
String urlStr = "http://localhost:7777/day18";
//2: Declare Url
URL url = new URL(urlStr+"/"+fileName);
//3: Get the connection
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
//4:Set the request method
con.setRequestMethod("GET");
//5: Get the request header, which is the length of the file
int length = con.getContentLength();//Get the length of the downloaded file to calculate the amount of data each thread should download.
//6: Create a file of the same size in the specified directory
RandomAccessFile file = new RandomAccessFile("d:/a/"+fileName, "rw");//Create a file of the same size.
//7: Set file size, placeholder
file.setLength(length);//Set the file size.
file.close();
//8: Define the number of threads
int size = 3;
//9: Calculate how many bytes of data each thread should download. If it is exactly divisible, it is best, otherwise add 1
int block = length/size==0?length/size:length/size+1;//Calculate the amount of data that each thread should download.
System.err.println("Each thread should download: "+block);
//10: Run three threads and calculate which byte starts and ends
for(int i=0;i<size;i++){
int start = i*block;
int end = start+(block-1);//Calculate the start and end bytes of each thread.
System.err.println(i+"="+start+","+end);
new MyDownThread(fileName, start, end,url).start();
}
}
static class MyDownThread extends Thread{
//Define file name
private String fileName;
//Define where to start downloading
private int start;
//Define which byte to download to
private int end;
private URL url;
public MyDownThread(String fileName,int start,int end,URL url){
this.fileName=fileName;
this.start=start;
this.end=end;
this.url=url;
}
@Override
public void run() {
try{
//11: Start downloading
HttpURLConnection con=
(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//12: Set the request header for segmented downloads
con.setRequestProperty("Range","bytes="+start+"-"+end);//Set the file blocks read from the server.
//13: Start downloading, need to judge 206
if(con.getResponseCode()==206){//The access is successful, the returned status code is 206.
InputStream in = con.getInputStream();
//14: Declare a random write file object. Note that rwd refers to writing data to the file immediately without using the cache area.
RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
out.seek(start);//Set to start writing data from a certain position in the file.
byte[] b=new byte[1024];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b,0,len);
}
out.close();
in.close();
}
System.err.println(this.getName()+"Execution completed");
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
}