public static class DownloadThread extends Thread{
private int threadId;
private int startIndex;
private int endIndex;
private int lastPostion;
public DownloadThread(int threadId,int startIndex,int endIndex){
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
@Override
public void run() {
synchronized (DownloadThread.class) {
runningTrheadCount = runningTrheadCount +1;//开启一线程,线程数加1
}
//分段请求网络连接,分段保存文件到本地
try{
URL url = new URL(path);
HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
openConnection.setRequestMethod("GET");
openConnection.setConnectTimeout(5*1000);
System.out.println("理论上下载: 线程:"+threadId+",开始位置:"+startIndex+";结束位置:"+endIndex);
//读取上次下载结束的位置,本次从这个位置开始直接下载。
File file2 = new File(threadId+".txt");
if(file2.exists()){
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file2)));
String lastPostion_str = bufferedReader.readLine();
lastPostion = Integer.parseInt(lastPostion_str);//读取文件获取上次下载的位置
//设置分段下载的头信息。 Range:做分段数据请求用的。
openConnection.setRequestProperty("Range", "bytes="+lastPostion+"-"+endIndex);//bytes:0-500:请求服务器资源中0-500之间的字节信息 501-1000:
System.out.println("实际下载1: 线程:"+threadId+",开始位置:"+lastPostion+";结束位置:"+endIndex);
bufferedReader.close();
}else{
lastPostion = startIndex;
//设置分段下载的头信息。 Range:做分段数据请求用的。
openConnection.setRequestProperty("Range", "bytes="+lastPostion+"-"+endIndex);//bytes:0-500:请求服务器资源中0-500之间的字节信息 501-1000:
System.out.println("实际下载2: 线程:"+threadId+",开始位置:"+lastPostion+";结束位置:"+endIndex);
}
System.out.println("getResponseCode"+openConnection.getResponseCode() );
if(openConnection.getResponseCode() == 206){//200:请求全部资源成功, 206代表部分资源请求成功
InputStream inputStream = openConnection.getInputStream();
//请求成功将流写入本地文件中,已经创建的占位那个文件中
RandomAccessFile randomAccessFile = new RandomAccessFile(filename, "rw");
randomAccessFile.seek(lastPostion);//设置随机文件从哪个位置开始写。
//将流中的数据写入文件
byte[] buffer = new byte[1024];
int length = -1;
int total = 0;//记录本次线程下载的总大小
while((length= inputStream.read(buffer)) !=-1){
randomAccessFile.write(buffer, 0, length);
total = total+ length;
//去保存当前线程下载的位置,保存到文件中
int currentThreadPostion = lastPostion + total;//计算出当前线程本次下载的位置
//创建随机文件保存当前线程下载的位置
File file = new File(threadId+".txt");
RandomAccessFile accessfile = new RandomAccessFile(file, "rwd");
accessfile.write(String.valueOf(currentThreadPostion).getBytes());
accessfile.close();
}
//关闭相关的流信息
inputStream.close();
randomAccessFile.close();
System.out.println("线程:"+threadId+",下载完毕");
//当所有线程下载结束,删除存放下载位置的文件。
synchronized (DownloadThread.class) {
runningTrheadCount = runningTrheadCount -1;//标志着一个线程下载结束。
if(runningTrheadCount == 0 ){
System.out.println("所有线程下载完成");
for(int i =0 ;i< threadCount;i++){
File file = new File(i+".txt");
System.out.println(file.getAbsolutePath());
file.delete();
}
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}
上面代码主要做了4 件事
1、设置分段下载的头信息;
2、分段下载网络资源
3、当中断时把当前各个线程当前下载的位置分别保存到一个临时文件中
4、下载完成后把临时文件删除 上面代码中都给出了详细的注释
其中有一点要注意
openConnection.setRequestProperty(“Range”, “bytes=”+lastPostion+”-“+endIndex);
如果”bytes=格式不对的话会导致设置不成功,返回的将不是部分资源的返回码
另一个要说明的就是randomAccessFile.seek(startThread);是设置各个线程下载的开始位置
Java多线程断点下载的更多相关文章
-
java多线程断点下载原理(代码实例演示)
原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...
-
java 多线程断点下载功能
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.Rand ...
-
Java多线程断点下载文件
Java实现断点续传+多线程下载 如下代码所示,每一步都有注解 思路: 通过URL连接到服务器上要下载的文件,得到文件的大小: 算出每条线程下载的开始位置和结束位置,例如,有两条线程下载100Byte ...
-
java 多线程断点下载demo
源码链接 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java ...
-
Android(java)学习笔记216:多线程断点下载的原理(Android实现)
之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...
-
Android(java)学习笔记159:多线程断点下载的原理(Android实现)
之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...
-
andoid 多线程断点下载
本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...
-
我的Android进阶之旅------>Android基于HTTP协议的多线程断点下载器的实现
一.首先写这篇文章之前,要了解实现该Android多线程断点下载器的几个知识点 1.多线程下载的原理,如下图所示 注意:由于Android移动设备和PC机的处理器还是不能相比,所以开辟的子线程建议不要 ...
-
iOS开发网络篇—大文件的多线程断点下载
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...
随机推荐
-
Linux FHS
学习linux有必要了解FHS的知识,FHS英文全称是Filesystem Hierarchy Standard.中文翻译就是文件系统层次结构标准.关于这个详细的介绍参考官方的文档和鸟哥linux书. ...
-
NSOperationQueue与GCD的使用原则和场景
首先,我们要明确NSOperationQueue与GCD之间的关系: NSOpertaionQueue用GCD构建封装的,是GCD的高级抽象. 其次,我们要区别两者的不同: GCD仅仅支持FIFO队列 ...
-
Linux常用命令之awk
标题:awk命令的使用 作用:awk是非常好用的数据处理工具,主要处理每一行的字段内的数据,默认的字段的分割符为空格键或[tab]键 一.awk脚本的基本结构: awk 'BEGIN{print &q ...
-
Arduino当avr开发板
原理并不复杂,因为arduino本来就是avr+一堆的库,找个能编译出hex的工具下载到板子就行. 但实际做起来还是碰到很多问题. 先是尝试eclipse+avr plugin 编译时出现make: ...
-
css基础知识之列表
ul.li列表样式部分如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
-
Dynamics CRM2016 Web API之删除
相比之前的增改查,删除就显得简单的多了. 这里的request的type为delete,删除成功的status为204,404则是要删除的记录不存在 var id = 'BAD90A95-7FEA-E ...
-
FileUtils功能概述
https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FileUtils.ht ...
-
C++实现wc.exe程序
github项目地址:https://github.com/insomniali/wc 基本功能 wc.exe -c file 统计文件file的字符数 [实现] wc.exe -w fil ...
-
WIN下的CMD下载命令
certutil -urlcache -split -f 远程地址 本地保存的文件跑径与文 件名 # 如里不写本地文 件名与路径名, 会自动跟远程文 件名相同, 并保存到当前目 录下 另一个是: bi ...
-
git提交代码到远程仓库
1.仓库初始化 git init 2.连接仓库 git remote add origin 仓库地址 3.查看状态 git status 4.将文件添加到暂存区 git add 状态里的新文件 5.将 ...