JAVA下實現多線程斷點下載


多線程斷點下載:顧名思義是用多線程實現的,斷點是當第三方因素(斷電、斷網等)中斷下載時,下次下載可以繼續上次下載的地方下載。

 

1、通過getContentLength可以獲取要下載文件的大小,這樣可以在本機上創建一個相同大小的文件用來下載。

int fileLength = connection.getContentLength();

2、由於是多線程,所以要給每一個線程均分分配要下載的位置。

for(int i = 0; i < threadCount; i ++) {
    int startThread = i * blockSize;
    int endThread = (i + 1) * blockSize - 1;
    if( i == blockSize - 1) endThread = fileLength -1;
    new DownloadThread(i, startThread, endThread).start();
                    
}

3、啟動每個線程下載時,請求頭需要Range參數,值是bytes:xxx-xxx某事。比如"Range:0-10100",代表要下載的位置是從0到10100。

connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);

4、然后每次用RandomAccessFile寫入數據到本機文件里。

while((length = inputStream.read(buffer)) != -1) {
    randomAccessFile.write(buffer, 0, length);
}

 

5、當然每次下載時需要記錄本線程下載了多少,以便斷點時,下載的時候可以從下次下載的地方下載。

total += length;
int currentThreadPostion = startThred + total;
RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
randomAccessFile2.close();

 

繼承Thread類的DownloadThread類代碼:

 1 public static class DownloadThread extends Thread {
 2         private int threadId;
 3         private int endThread;
 4         private int startThred;
 5         public DownloadThread(int threadId, int startThred, int endThread) {
 6             this.threadId = threadId;
 7             this.startThred = startThred;
 8             this.endThread = endThread;
 9         }
10         public void run() {
11             //分段請求網絡連接,分段保存在本地
12             synchronized (DownloadThread.class) {
13                 currentRunThreadCount += 1;
14             }
15             try {
16                 System.err.println("理論線程:"+threadId+",開始位置:"+startThred+",結束位置:"+endThread);
17                 URL url = new URL(path);
18                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
19                 connection.setRequestMethod("GET");
20                 connection.setConnectTimeout(10 * 1000);
21                 File file = new File(threadId+".txt");
22                 if(file.exists()) {    //是否斷點
23                     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
24                     String lastPostion_str = bufferedReader.readLine();
25                     startThred = Integer.parseInt(lastPostion_str);
26                     bufferedReader.close();
27                 }
28                 //設置分段下載的頭信息  Range:做分段
29                 connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);
30                 int code = connection.getResponseCode();
31                 System.out.println(code);
32                 if(code == 200) {    //200:請求全部資源成功  206:代表部分資源請求成功
33                     InputStream inputStream = connection.getInputStream();
34                     System.out.println(getFileName(path));
35                     RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
36                     randomAccessFile.seek(startThred);
37                     byte[] buffer = new byte[1024*10];
38                     int length = -1;
39                     int total = 0;//記錄下載的總量
40                     System.err.println("實際線程:"+threadId+",開始位置:"+startThred+",結束位置:"+endThread);
41                     while((length = inputStream.read(buffer)) != -1) {
42                         randomAccessFile.write(buffer, 0, length);
43                         total += length;
44                         int currentThreadPostion = startThred + total;
45                         RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
46                         randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
47                         randomAccessFile2.close();
48                     }
49                     randomAccessFile.close();
50                     inputStream.close();
51                     System.err.println("線程:"+threadId+"下載完畢");
52                     synchronized (DownloadThread.class) {
53                         currentRunThreadCount -= 1;
54                         if(currentRunThreadCount == 0){
55                             for(int i = 0; i < threadCount; i ++) {
56                                 File file2 = new File(i+".txt");
57                                 file2.delete();
58                             }
59                         }
60                     }
61                 }
62                 
63             } catch (Exception e) {
64                 e.printStackTrace();
65             }
66             
67              
68             super.run();
69         }
70     }
View Code

 

完整代碼:

  1 import java.io.BufferedReader;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.InputStream;
  5 import java.io.InputStreamReader;
  6 import java.io.RandomAccessFile;
  7 import java.net.HttpURLConnection;
  8 import java.net.URL;
  9 
 10 
 11 public class exp6 {
 12 
 13     /**
 14      * @param args
 15      */
 16     private static int threadCount = 3;
 17     private static int blockSize;
 18     private static String path = "http://starry97.cn/a.txt";
 19     private static int currentRunThreadCount = 0;
 20     public static void main(String[] args) {
 21         
 22         try {
 23             URL url = new URL(path);
 24             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 25             connection.setRequestMethod("GET");
 26             connection.setConnectTimeout(10 * 1000);
 27             int code = connection.getResponseCode();
 28             if(code == 200) {
 29                 int fileLength = connection.getContentLength();
 30                 RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
 31                 randomAccessFile.setLength(fileLength);
 32                 blockSize = fileLength / threadCount;
 33                 for(int i = 0; i < threadCount; i ++) {
 34                     int startThread = i * blockSize;
 35                     int endThread = (i + 1) * blockSize - 1;
 36                     if( i == blockSize - 1) endThread = fileLength -1;
 37                     new DownloadThread(i, startThread, endThread).start();
 38                     
 39                 }
 40             }
 41         } catch (Exception e) {
 42             e.printStackTrace();
 43         }
 44         
 45     }
 46     
 47     
 48     public static class DownloadThread extends Thread {
 49         private int threadId;
 50         private int endThread;
 51         private int startThred;
 52         public DownloadThread(int threadId, int startThred, int endThread) {
 53             this.threadId = threadId;
 54             this.startThred = startThred;
 55             this.endThread = endThread;
 56         }
 57         public void run() {    
 58             synchronized (DownloadThread.class) {
 59                 currentRunThreadCount += 1;
 60             }
 61             //分段請求網絡連接,分段保存在本地
 62             try {
 63                 System.err.println("理論線程:"+threadId+",開始位置:"+startThred+",結束位置:"+endThread);
 64                 URL url = new URL(path);
 65                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 66                 connection.setRequestMethod("GET");
 67                 connection.setConnectTimeout(10 * 1000);
 68                 File file = new File(threadId+".txt");
 69                 if(file.exists()) {    //是否斷點
 70                     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
 71                     String lastPostion_str = bufferedReader.readLine();
 72                     startThred = Integer.parseInt(lastPostion_str);
 73                     bufferedReader.close();
 74                 }
 75                 //設置分段下載的頭信息  Range:做分段
 76                 connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);
 77                 int code = connection.getResponseCode();
 78                 System.out.println(code);
 79                 if(code == 200) {    //200:請求全部資源成功  206:代表部分資源請求成功
 80                     InputStream inputStream = connection.getInputStream();
 81                     System.out.println(getFileName(path));
 82                     RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
 83                     randomAccessFile.seek(startThred);
 84                     byte[] buffer = new byte[1024*10];
 85                     int length = -1;
 86                     int total = 0;//記錄下載的總量
 87                     System.err.println("實際線程:"+threadId+",開始位置:"+startThred+",結束位置:"+endThread);
 88                     while((length = inputStream.read(buffer)) != -1) {
 89                         randomAccessFile.write(buffer, 0, length);
 90                         total += length;
 91                         int currentThreadPostion = startThred + total;
 92                         RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
 93                         randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
 94                         randomAccessFile2.close();
 95                     }
 96                     randomAccessFile.close();
 97                     inputStream.close();
 98                     System.err.println("線程:"+threadId+"下載完畢");
 99                     synchronized (DownloadThread.class) {
100                         currentRunThreadCount -= 1;
101                         if(currentRunThreadCount == 0){
102                             for(int i = 0; i < threadCount; i ++) {
103                                 File file2 = new File(i+".txt");
104                                 file2.delete();
105                             }
106                         }
107                     }
108                 }
109                 
110             } catch (Exception e) {
111                 e.printStackTrace();
112             }
113             
114              
115             super.run();
116         }
117     }
118     
119     public static String getFileName(String path) {
120         return path.substring(path.lastIndexOf("/")+1);
121     }
122 
123 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM