源码链接

 import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection; public class MutileThreadDownload {
/**
* 线程的数量
*/
private static int threadCount = 3;
/**
* 每个下载区块的大小
*/
private static long blocksize;
/**
* 正在运行的线程的数量
*/
private static int runningThreadCount;
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//服务器路径
String path = "http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/chm/JDK_API_1_6_zh_CN.CHM";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
int code = conn.getResponseCode();
if(code == 200) {
long size = conn.getContentLength();//得到服务器端返回的文件的大小
System.out.println("服务器文件的大小:" + size);
blocksize = size / threadCount;
//1.首先在本地创建一个大小跟服务器一模一样的空白文件
File file = new File("temp.CHM");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.setLength(size);
//2.开启若干个子线程分别去下载对应的资源
runningThreadCount = threadCount;
for(int i = 1;i <= threadCount; i++) {
long startIndex = (i - 1) * blocksize;
long endIndex = i * blocksize - 1;
if(i == threadCount) {
//最后一个线程
endIndex = size - 1;
}
System.out.println("开启线程:" + i + "下载的位置:" + startIndex + "~" + endIndex);
new DownloadThread(i, startIndex, endIndex, path).start();
}
}
conn.disconnect();
} private static class DownloadThread extends Thread {
private int threadId;
private long startIndex;
private long endIndex;
private String path; public DownloadThread(int threadId, long startIndex, long endIndex,
String path) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
} public void run() {
try {
//当前线程下载的总大小
int total = 0;
File positionFile = new File(threadId + ".txt");
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//接着从上一次的位置继续下载数据
if(positionFile.exists() && positionFile.length() > 0) { //判断是否有记录
FileInputStream fis = new FileInputStream(positionFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
//获取当前线程上次下载的总大小是多少
String lasttotalstr = br.readLine();
int lastTotal = Integer.valueOf(lasttotalstr);
System.out.println("上次线程" + threadId + "下载的总大小:" + lastTotal);
startIndex += lastTotal; //加上上次下载的总大小
fis.close();
} conn.setRequestProperty("Range", "bytes=" + startIndex + "-" +endIndex);
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
System.out.println("code=" + code);
InputStream is = conn.getInputStream();
File file = new File("temp.CHM");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(startIndex);
System.out.println("第" + threadId + "个线程:写文件的开始位置:" + String.valueOf(startIndex)); int len = 0;
byte[] buffer = new byte[1024 * 1024];
while((len = is.read(buffer)) != -1) {
RandomAccessFile rf = new RandomAccessFile(positionFile, "rwd");//"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。
raf.write(buffer, 0, len);
total += len;
rf.write(String.valueOf(total).getBytes());
rf.close();
}
is.close();
raf.close();
//conn.disconnect(); } catch (Exception e) {
e.printStackTrace();
}finally {
//只有所有线程都下载完毕后,才可以删除记录文件
synchronized (MutileThreadDownload.class) { //线程安全
System.out.println("线程" + threadId + "下载完毕了");
runningThreadCount--;
if(runningThreadCount < 1) {
System.out.println("所有线程都工作完毕了。删除临时记录的文件");
for (int i = 1; i <= threadCount; i++) {
File f = new File(i + ".txt");
System.out.println(f.delete());
}
}
}
}
}
}
}

java 多线程断点下载demo的更多相关文章

  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

    //1.声明URL String path="http://localhost:8080/day22_DownLoad/file/a.rmvb"; URL url=new URL( ...

  5. Java多线程断点下载

    public static class DownloadThread extends Thread{ private int threadId; private int startIndex; pri ...

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

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

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

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

  8. 33、多线程断点下载的实现&界面的更新

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  9. andoid 多线程断点下载

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

随机推荐

  1. 自动化回归测试案例评价标准 MeRest

    自动化回归测试案例评价标准试图定义不同维度来评价自动化案例的优劣,作为后续我们评判讨论测试框架.测试技术和测试案例编写模式的基础.那什么是好的自动化回归测试案例呢?简而言之,就是投资回报率高的案例,因 ...

  2. MySQL不能插入中文字符及中文字符乱码问题

    MySQL的默认编码是Latin1,不支持中文,要支持中午需要把数据库的默认编码修改为gbk或者utf8.在安装后MySQL之后,它的配置文件不是很给力,不知道你们的是不是,反正我的是! 开始插入中文 ...

  3. HMM 自学教程(四)隐马尔科夫模型

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  4. 直接拿来用!最火的Android开源项目

    GitHub在中国的火爆程度无需多言,越来越多的开源项目迁移到GitHub平台上.更何况,基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要.利用这些项目,有时能够让你 ...

  5. 谈Mysql索引

    myisam和innodb的索引有什么区别? 两个索引都是B+树索引,但是myisam的表存储和索引存储是分开的,索引存储中存放的是表的地址.而innodb表存储本身就是一个B+树,它是用主键来做B+ ...

  6. P6 EPPM R16.1安装与配置指南(一)

    标题 http://www.cnblogs.com/endv/p/5634620.html 安装与配置指南安装与配置指南(数据库)说明哪些How to set up the P6专业数据库和服务器.a ...

  7. ASP.NET文本框密码赋默认值的方法

    对于普通的文本输入框,可以使用下边的方法赋默认值: <asp:TextBox ID="TextBox1" runat="server">12345& ...

  8. html5菜单折纸效果

    类似猎豹浏览器安装时的用户须知效果. html文件代码,保存为html文件打开: <!DOCTYPE html> <html> <head> <meta ht ...

  9. 客户端(Winform窗体)上传文件到服务器(web窗体)简单例子

    客户端:先创建一个winform窗体的应用程序项目 项目结构

  10. X3DOM新增剪裁平面节点ClipPlane支持

    裁剪平面由方程Ax+By+Cz+D=0确定.所有满足[A B C D]M-1[Xe Ye Ze We]T>0的人眼坐标[Xe Ye Ze We]的点都位于该平面定义的半空间中,而该半空间以外的所 ...