Java multi threaded download method

  • 2020-04-01 01:34:07
  • OfStack


package cn.me.test;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 *  Multithreaded download 
 * 1 Use: RandomAccessFile Writes data to any location. 
 * 2 : the amount of data to be downloaded by the first thread needs to be calculated and can be distributed equally. If it's not equal, 
 *     The last thread handles relatively little data directly 
 * 3 : files of the same size must be prepared before downloading 
 */
public class MultiThreadDownload {
    public static void main(String[] args) throws Exception {
       //1: declare file name and download address
       String fileName = "aa.rar";
       String urlStr = "http://localhost:7777/day18";
       //2: declare the Url
       URL url = new URL(urlStr+"/"+fileName);
       //3: get the connection
       HttpURLConnection con =
           (HttpURLConnection) url.openConnection();
       //4: set the request mode
       con.setRequestMethod("GET");
       //5: gets the request header, that is, the length of the file
       int length = con.getContentLength();//Gets the length of the downloaded file to calculate how much 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 the file size and hold the space
       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, preferably if it is exactly divisible, otherwise add 1
       int block = length/size==0?length/size:length/size+1;//Calculates 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 to start and which byte to end
       for(int i=0;i<size;i++){
           int start = i*block;
           int end = start+(block-1);//Calculates 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;
       //Defines which bytes 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: sets the request header for segmented downloads
              con.setRequestProperty("Range","bytes="+start+"-"+end);//Sets the file blocks to be read from the server.
 
              //13: start downloading, need to judge 206
              if(con.getResponseCode()==206){//If the access is successful, the status code returned is 206.
                  InputStream in = con.getInputStream();
                  //14: declare a random write file object. Note that RWD means writing data to a file immediately without using a cache
                  RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");
                  out.seek(start);//Set to start writing data from somewhere 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()+" completes ");
           }catch(Exception e){
              throw new RuntimeException(e);
           }
       }
    }
}


Related articles: