多线程断点续传

时间:2022-09-04 18:54:10
 1 import java.io.InputStream;
 2 import java.io.RandomAccessFile;
 3 import java.net.HttpURLConnection;
 4 import java.net.URL;
 5 
 6 public class FileDownLoader {
 7     
 8     public void download() throws Exception {
 9         String path = "http://browse.babasport.com/QQWubiSetup.exe";
10         URL url = new URL(path);
11         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
12         conn.setConnectTimeout(5*1000);
13         conn.setRequestMethod("GET");
14         conn.setRequestProperty("Accept", "image/gif, image/jpeg, " +
15                 "image/pjpeg, image/pjpeg, application/x-shockwave-flash, " +
16                 "application/xaml+xml, application/vnd.ms-xpsdocument, " +
17                 "application/x-ms-xbap, application/x-ms-application, " +
18                 "application/vnd.ms-excel, application/vnd.ms-powerpoint, " +
19                 "application/msword, */*");
20         conn.setRequestProperty("Accept-Language", "zh-CN");
21         conn.setRequestProperty("Charset", "UTF-8");
22         conn.setRequestProperty("User-Agent", "Mozilla/4.0 " +
23                 "(compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0;" +
24                 " .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; " +
25                 ".NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
26         conn.setRequestProperty("Connection", "Keep-Alive");
27         System.out.println(conn.getResponseCode());
28         
29         int filesize = conn.getContentLength();//得到文件大小
30         conn.disconnect();
31         int threasize = 3;//线程数
32         int perthreadsize = filesize / 3 + 1;
33         RandomAccessFile file = new RandomAccessFile("102.wma","rw");
34         file.setLength(filesize);//设置本地文件的大小
35         file.close();
36         for(int i=0; i<threasize ; i++){
37             int startpos = i * perthreadsize;//计算每条线程的下载位置
38             RandomAccessFile perthreadfile = new RandomAccessFile("102.wma","rw");//
39             perthreadfile.seek(startpos);//从文件的什么位置开始写入数据
40             new DownladerThread(i, path, startpos, perthreadsize, perthreadfile).start();
41         }
42         //以下代码要求用户输入q才会退出测试方法,如果没有下面代码,会因为进程结束而导致进程内的下载线程被销毁
43         int quit = System.in.read();
44         while('q'!=quit){
45             Thread.sleep(2 * 1000);
46         }
47     }
48     
49     private class DownladerThread extends Thread{
50         private int startpos;//从文件的什么位置开始下载
51         private int perthreadsize;//每条线程需要下载的文件大小
52         private String path;
53         private RandomAccessFile file;
54         private int threadid;
55         
56         public DownladerThread(int threadid, String path, int startpos, int perthreadsize, RandomAccessFile perthreadfile) {
57             this.path = path;
58             this.startpos = startpos;
59             this.perthreadsize = perthreadsize;
60             this.file = perthreadfile;
61             this.threadid = threadid;
62         }
63         
64         @Override
65         public void run() {
66             try {
67             URL url = new URL(path);
68             HttpURLConnection conn = (HttpURLConnection)url.openConnection();
69             conn.setConnectTimeout(5 * 1000);
70             conn.setRequestMethod("GET");
71             conn.setRequestProperty("Accept", "image/gif, image/jpeg, " +
72                     "image/pjpeg, image/pjpeg, application/x-shockwave-flash, " +
73                     "application/xaml+xml, application/vnd.ms-xpsdocument, " +
74                     "application/x-ms-xbap, application/x-ms-application, " +
75                     "application/vnd.ms-excel, application/vnd.ms-powerpoint, " +
76                     "application/msword, */*");
77             conn.setRequestProperty("Accept-Language", "zh-CN");
78             conn.setRequestProperty("Charset", "UTF-8");
79             conn.setRequestProperty("Range", "bytes=" + this.startpos + "-");
80             InputStream inStream = conn.getInputStream();
81             byte[] buffer = new byte[1024];
82             int len = 0;
83             int length = 0;
84             while(length<perthreadsize && (len = inStream.read(buffer))!=-1){
85                 file.write(buffer, 0, len);
86                 length += len;//累计该线程下载的总大小
87             }
88             file.close();
89             inStream.close();
90             System.out.println(threadid+ "线程完成下载");
91         } catch (Exception e) {
92             e.printStackTrace();
93         }
94     }
95     }
96 
97 }