多線程斷點續傳下載

使用多線程下載文件能夠更快的完成文件的下載,多線程下載之因此快,是由於其搶佔的服務器資源多。 服務器

多線程下載實現的過程: 多線程

1,首先獲得下載文件的長度,而後設置本地文件的長度 app

    HttpURLConnection.getContentLength(); dom

    RandomAccessFile file=new RandowAccessFile("qq.exe","rwd"); ide

    file.setLength(filesize);//設置本地文件的長度 測試

2,根據文件長度和線程數計算每條線程下載的數據長度和下載位置 ui

3,使用Http的Range字段指定每條線程從文件的什麼位置下載,下載到什麼位置 this

     HttpURLConnection.setRequestProperty("Range","byte=500-20000"); url

4,保存文件,使用RandomAccessFile類指定每條線程從本地文件的什麼位置開始寫入數據 spa

    RandomAccessFile file=new RandowAccessFile("qq.exe","rwd");

    file.seek(500);//設置從文件的什麼位置開始寫入數據

 

public class FileDownLoader {

  @Test

  public void download() throws Exception {

  String path = "http://www.qq.com/qq.exe";

  URL url = new URL(path);

  HttpURLConnection conn = (HttpURLConnection) url.openConnection();

  conn.setConnectTimeout(5*1000);

  conn.setRequestMethod("GET");

  conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

  conn.setRequestProperty("Accept-Language", "zh-CN");

  conn.setRequestProperty("Charset", "UTF-8");

  conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");

  conn.setRequestProperty("Connection", "Keep-Alive");

  System.out.println(conn.getResponseCode());

 

  int filesize = conn.getContentLength();//獲得文件大小

  conn.disconnect();

  int threasize = 3;//線程數

  int perthreadsize = filesize / 3 + 1;

  RandomAccessFile file = new RandomAccessFile("102.wma","rw");

  file.setLength(filesize);//設置本地文件的大小

  file.close();

  for(int i=0; i<threasize ; i++){

  int startpos = i * perthreadsize;//計算每條線程的下載位置

  RandomAccessFile perthreadfile = new RandomAccessFile("102.wma","rw");//

  perthreadfile.seek(startpos);//從文件的什麼位置開始寫入數據

  new DownladerThread(i, path, startpos, perthreadsize, perthreadfile).start();

  }

  //如下代碼要求用戶輸入q纔會退出測試方法,若是沒有下面代碼,會由於進程結束而致使進程內的下載線程被銷燬

  int quit = System.in.read();

  while('q'!=quit){

  Thread.sleep(2 * 1000);

  }

  }

 

  private class DownladerThread extends Thread{

  private int startpos;//從文件的什麼位置開始下載

  private int perthreadsize;//每條線程須要下載的文件大小

  private String path;

  private RandomAccessFile file;

  private int threadid;

 

  public DownladerThread(int threadid, String path, int startpos, int perthreadsize, RandomAccessFile perthreadfile) {

  this.path = path;

  this.startpos = startpos;

  this.perthreadsize = perthreadsize;

  this.file = perthreadfile;

  this.threadid = threadid;

  }

 

  @Override

  public void run() {

  try {

  URL url = new URL(path);

  HttpURLConnection conn = (HttpURLConnection)url.openConnection();

  conn.setConnectTimeout(5 * 1000);

  conn.setRequestMethod("GET");

  conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

  conn.setRequestProperty("Accept-Language", "zh-CN");

  conn.setRequestProperty("Charset", "UTF-8");

  conn.setRequestProperty("Range", "bytes=" + this.startpos + "-");

  InputStream inStream = conn.getInputStream();

  byte[] buffer = new byte[1024];

  int len = 0;

  int length = 0;

  while(length<perthreadsize && (len = inStream.read(buffer))!=-1){

  file.write(buffer, 0, len);

  length += len;//累計該線程下載的總大小

  }

  file.close();

  inStream.close();

  System.out.println(threadid+ "線程完成下載");

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  }

}

相關文章
相關標籤/搜索