java 多线程下载 断点_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;newDownloadThread(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类代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public static class DownloadThread extendsThread {2 private intthreadId;3 private intendThread;4 private intstartThred;5 public DownloadThread(int threadId, int startThred, intendThread) {6 this.threadId =threadId;7 this.startThred =startThred;8 this.endThread =endThread;9 }10 public voidrun() {11 //分段请求网络连接,分段保存在本地

12 synchronized (DownloadThread.class) {13 currentRunThreadCount += 1;14 }15 try{16 System.err.println("理论线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);17 URL url = newURL(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(newFileInputStream(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

完整代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importjava.io.BufferedReader;2 importjava.io.File;3 importjava.io.FileInputStream;4 importjava.io.InputStream;5 importjava.io.InputStreamReader;6 importjava.io.RandomAccessFile;7 importjava.net.HttpURLConnection;8 importjava.net.URL;9

10

11 public classexp6 {12

13 /**

14 *@paramargs15 */

16 private static int threadCount = 3;17 private static intblockSize;18 private static String path = "http://starry97.cn/a.txt";19 private static int currentRunThreadCount = 0;20 public static voidmain(String[] args) {21

22 try{23 URL url = newURL(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 newDownloadThread(i, startThread, endThread).start();38

39 }40 }41 } catch(Exception e) {42 e.printStackTrace();43 }44

45 }46

47

48 public static class DownloadThread extendsThread {49 private intthreadId;50 private intendThread;51 private intstartThred;52 public DownloadThread(int threadId, int startThred, intendThread) {53 this.threadId =threadId;54 this.startThred =startThred;55 this.endThread =endThread;56 }57 public voidrun() {58 synchronized (DownloadThread.class) {59 currentRunThreadCount += 1;60 }61 //分段请求网络连接,分段保存在本地

62 try{63 System.err.println("理论线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);64 URL url = newURL(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(newFileInputStream(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 staticString getFileName(String path) {120 return path.substring(path.lastIndexOf("/")+1);121 }122

123 }

View Code

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值