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多线程断点下载的更多相关文章

  1. java多线程断点下载原理(代码实例演示)

    原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...

  2. java 多线程断点下载功能

    import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.Rand ...

  3. Java多线程断点下载文件

    Java实现断点续传+多线程下载 如下代码所示,每一步都有注解 思路: 通过URL连接到服务器上要下载的文件,得到文件的大小: 算出每条线程下载的开始位置和结束位置,例如,有两条线程下载100Byte ...

  4. java 多线程断点下载demo

    源码链接 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java ...

  5. Android(java)学习笔记216:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...

  6. Android(java)学习笔记159:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...

  7. andoid 多线程断点下载

    本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...

  8. 我的Android进阶之旅------>Android基于HTTP协议的多线程断点下载器的实现

    一.首先写这篇文章之前,要了解实现该Android多线程断点下载器的几个知识点 1.多线程下载的原理,如下图所示 注意:由于Android移动设备和PC机的处理器还是不能相比,所以开辟的子线程建议不要 ...

  9. iOS开发网络篇—大文件的多线程断点下载

    http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...

随机推荐

  1. 032. asp.netWeb用户控件之一初识用户控件并为其自定义属性

    Web用户控件的优点: 可以将常用的内容或者控件以及控件的运行程序逻辑, 设计为用户控件, 以后便可以在多个页面中重复使用该用户控件, 从而省去许多重复性的工作. 如网页上的导航栏, 几乎每个页面都需 ...

  2. LNMP编译安装教程

    LNMP编译安装教程 此次安装在Centos上,我采用的CentOS的版本是:CentOS release 6.5 (Final) 可以通过以下命令查看:lsb_release -a 一.准备工作: ...

  3. windows环境下,如何启动chromedriver

    java -jar selenium-server-standalone-2.41.0.jar -Dwebdriver.chrome.driver="C:\Program Files\Goo ...

  4. phpnow修改默认站点根目录的方法

    本文转载自:http://blog.csdn.net/andy_eeipla/article/details/7832082 对于phpnow,经测试,修改Apache-20\conf\extra\h ...

  5. python学习-day03:整形、字符串常用方法:

    一.数字,int 1.1: a.int(object)转化数字类型: a=' b=int(a) b=b+1000 print(b) 223 <class 'int'> 答案 b.转化二进制 ...

  6. 使用springMVC实现文件上传和下载之环境配置与上传

    最近的项目中用到了文件的上传和下载功能,任务分配给了其他的同时完成.如今项目结束告一段落,我觉着这个功能比较重要,因此特意把它提取出来自己进行了尝试. 一. 基础配置: maven导包及配置pom.x ...

  7. overload, override和overwrite之间的区别

    Overload.Overwrite和Override的概念比较容易混淆,而且Overwrite和Override的中文翻译五花八门,让人很Confuse,顾保持英文原意: Overload  重载 ...

  8. shell script练习

    执行脚本的几种方式: 1. sh a.sh 或者  bash a.sh  调用的是 /bin/bash 进程执行的,所以脚本不需要执行权限. 2. 直接使用绝对路径执行, /home/script/a ...

  9. 实现远程连接ACCESS数据库的方法

    使用了TCP/IP,ADO及(需要安装Microsoft 4.0.).分服务器和客户端两部分,可以多用户同时连接.远程连接Access有很多方法,我以前已经比较详细的回答过(见下面所列的5种方法),我 ...

  10. path和classpath

    对于Java的初学者,这两个环境变量,总是要遇到的.这里做一下总结. 1.path和classpath的含义 path是Windows操作系统的一个环境变量. 当操作系统需要运行一个程序,它需要知道该 ...