程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java多線程下載的實現方法

Java多線程下載的實現方法

編輯:JAVA編程入門知識

代碼如下:

package cn.me.test;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

/**

 * 多線程下載

 * 1:使用RandomAccessFile在任意的位置寫入數據。

 * 2:需要計算第一個線程下載的數據量,可以平均分配。如果不夠平均時,

 *    則直接最後一個線程處理相對較少的數據

 * 3:必須要在下載之前准備好相同大小的文件,通過文件頭獲取

 */

public class MultiThreadDownload {

    public static void main(String[] args) throws Exception {

       //1:聲明文件名和下載的地址

       String fileName = "aa.rar";

       String urlStr = "http://localhost:7777/day18";

       //2:聲明Url

       URL url = new URL(urlStr+"/"+fileName);

       //3:獲取連接

       HttpURLConnection con =

           (HttpURLConnection) url.openConnection();

       //4:設置請求方式

       con.setRequestMethod("GET");

       //5:獲取請求頭,即文件的長度

       int length = con.getContentLength();//獲取下載文件的長度,以計算每個線程應該下載的數據量。

       //6:在指定的目錄下,創建一個同等大小的文件

       RandomAccessFile file = new RandomAccessFile("d:/a/"+fileName, "rw");//創建一個相同大小的文件。

       //7:設置文件大小,占位

       file.setLength(length);//設置文件大小。

       file.close();

       //8:定義線程個數

       int size = 3;

       //9:計算每一個線程應該下載多少字節的數據,如果正好整除則最好,否則加1

       int block = length/size==0?length/size:length/size+1;//計算每個線程應該下載的數據量。

       System.err.println("每個線程應該下載:"+block);

       //10:運行三個線程並計算從哪個字節開始到哪一個字節結束

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

           int start = i*block;

           int end = start+(block-1);//計算每一個線程的開始和結束字節。

         System.err.println(i+"="+start+","+end);

           new MyDownThread(fileName, start, end,url).start();

       }

    }

    static class MyDownThread extends Thread{

       //定義文件名

       private String fileName;

       //定義從何地開始下載

       private int start;

       //定義下載到哪一個字節

       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:開始下載

              HttpURLConnection con =

                     (HttpURLConnection) url.openConnection();

              con.setRequestMethod("GET");

              //12:設置分段下載的請求頭

              con.setRequestProperty("Range","bytes="+start+"-"+end);//設置從服務器上讀取的文件塊。

              //13:開始下載,需要判斷206

              if(con.getResponseCode()==206){//訪問成功,則返回的狀態碼為206。

                  InputStream in = con.getInputStream();

                  //14:聲明隨機寫文件對象,注意rwd是指即時將數據寫到文件中,而不使用緩存區

                  RandomAccessFile out = new RandomAccessFile("d:/a/"+fileName,"rwd");

                  out.seek(start);//設置從文件的某個位置開始寫數據。

                  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()+"執行完成");

           }catch(Exception e){

              throw new RuntimeException(e);

           }

       }

    }

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved