使用多線程去下載同一個文件

 1 import java.io.InputStream;
 2 import java.io.RandomAccessFile;
 3 import java.net.HttpURLConnection;
 4 import java.net.URL;
 5 
 6 public class Demo {
 7     public static String path = "<a target="_blank" href="http://softdownload.hao123.com/hao123-soft-online-bcs/soft/Y/2013-07-18_YoudaoDict_baidu.alading.exe">http://softdownload.hao123.com/hao123-soft-online-bcs/soft/Y/2013-07-18_YoudaoDict_baidu.alading.exe</a>";
 8     public static int threadCount = 3;
 9     public static void main(String[] args) throws Exception{
10         //1.鏈接服務器,獲取一個文件,獲取文件的長度,在本地建立一個跟服務器同樣大小的臨時文件
11         URL url = new URL(path);
12         HttpURLConnection conn = (HttpURLConnection)url.openConnection();
13         conn.setConnectTimeout(5000);
14         conn.setRequestMethod("GET");
15         int code = conn.getResponseCode();
16         if (code == 200) {
17             //服務器端返回的數據的長度,實際上就是文件的長度
18             int length = conn.getContentLength();
19             System.out.println("文件總長度:"+length);
20             //在客戶端本地建立出來一個大小跟服務器端同樣大小的臨時文件
21             RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");
22             //指定建立的這個文件的長度
23             raf.setLength(length);
24             raf.close();
25             //假設是3個線程去下載資源。
26             //平均每個線程下載的文件大小.
27             int blockSize = length / threadCount;
28             for (int threadId = 1; threadId <= threadCount; threadId++) {
29                 //第一個線程下載的開始位置
30                 int startIndex = (threadId - 1) * blockSize;
31                 int endIndex = threadId * blockSize - 1;
32                 if (threadId == threadCount) {//最後一個線程下載的長度要稍微長一點
33                     endIndex = length;
34                 }
35                 System.out.println("線程:"+threadId+"下載:---"+startIndex+"--->"+endIndex);
36                 new DownLoadThread(path, threadId, startIndex, endIndex).start();
37             }
38         
39         }else {
40             System.out.printf("服務器錯誤!");
41         }
42     }
43     
44     /**
45      * 下載文件的子線程  每個線程下載對應位置的文件
46      * @author jie
47      *
48      */
49     public static class DownLoadThread extends Thread{
50         private int threadId;
51         private int startIndex;
52         private int endIndex;
53         /**
54          * @param path 下載文件在服務器上的路徑
55          * @param threadId 線程Id
56          * @param startIndex 線程下載的開始位置
57          * @param endIndex    線程下載的結束位置
58          */
59         public DownLoadThread(String path, int threadId, int startIndex, int endIndex) {
60             super();
61             this.threadId = threadId;
62             this.startIndex = startIndex;
63             this.endIndex = endIndex;
64         }
65 
66         @Override
67         public void run() {
68             try {
69                 URL url = new URL(path);
70                 HttpURLConnection conn = (HttpURLConnection)url.openConnection();
71                 conn.setConnectTimeout(5000);
72                 conn.setRequestMethod("GET");
73                 //重要:請求服務器下載部分文件 指定文件的位置
74                 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
75                 //從服務器請求所有資源返回200 ok若是從服務器請求部分資源 返回 206 ok
76                 int code = conn.getResponseCode();
77                 System.out.println("code:"+code);
78                 InputStream is = conn.getInputStream();//已經設置了請求的位置,返回的是當前位置對應的文件的輸入流
79                 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");
80                 //隨機寫文件的時候從哪一個位置開始寫
81                 raf.seek(startIndex);//定位文件
82             
83                 int len = 0;
84                 byte[] buffer = new byte[1024];
85                 while ((len = is.read(buffer)) != -1) {
86                     raf.write(buffer, 0, len);
87                 }
88                 is.close();
89                 raf.close();
90                 System.out.println("線程:"+threadId+"下載完畢");
91             } catch (Exception e) {
92                 e.printStackTrace();
93             }
94         }
95         
96     }
97 }
相關文章
相關標籤/搜索