多线程断点下载:顾名思义是用多线程实现的,断点是当第三方因素(断电、断网等)中断下载时,下次下载可以继续上次下载的地方下载。

 

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

相关文章: