【转】【JAVA应用】多线程断点下载
【转自】
光仔December
问题:多线程下载的好处?
多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源。抢占Cpu的处理空间,实现更快的下载速度
问题:多线程下载位置的确定?
开启N条线程下载文件,假设文件大小为buf,那么每条线程的下载量为:
buf%N==0?buf/N:buf/N+1;
那么,每一条线程应该从网络文件的什么位置开始下载??
假设线程id号threadid为0,1,2,每一条线程下载的数据量为block=4
第一个文件从threadid*block开始下载,结束位置(threadid+1)*block-1
所以公式为:
int start=threadid*block;
int end=(threadid+1)*block-1;
多线程下载源码(仅供参考)
- package cn.deu.hpu.download;
- import java.io.File;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class MulThreadDownLoad {
- public static void main(String[] args) throws Exception{
- String path="http://192.168.111.104:8080/web/gg.jpg";
- new MulThreadDownLoad().download(path,3);
- }
- /*下载文件
- * path 网络文件路径
- * */
- public void download(String path,int threadsize)throws Exception{
- URL url=new URL(path);
- HttpURLConnection conn=(HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(5000);
- conn.setRequestMethod("GET");
- if(conn.getResponseCode()==200){
- //取得网络文件的长度
- int length=conn.getContentLength();
- File file=new File(getFilename(path));
- //随机访问文件类(生成一个与网络文件长度相等的本地文件)
- RandomAccessFile accessFile=new RandomAccessFile(file, "rwd");
- accessFile.setLength(length);
- accessFile.close();
- //计算每条线程需要下载的数据量
- int block=length%threadsize==0?length/threadsize:length/threadsize+1;
- for (int threadid = 0; threadid< threadsize; threadid++) {
- new DownloadThread(threadid,block,url,file).start();
- }
- }else{
- System.out.println("下载失败!");
- }
- }
- private String getFilename(String path) {
- //从URL地址的最后一个"/"后开始记录文件名
- return path.substring(path.lastIndexOf("/")+1);
- }
- private class DownloadThread extends Thread{
- private int threadid;
- private int block;
- private URL url;
- private File file;
- public DownloadThread(int threadid,int block,URL url,File file){
- this.threadid=threadid;
- this.block=block;
- this.url=url;
- this.file=file;
- }
- public void run(){
- //计算该线程从网络文件的什么位置开始下载
- int start=threadid*block;
- //下载到网络文件的什么位置结束
- int end=(threadid+1)*block-1;
- try {
- RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
- //从某一个位置开始写入数据
- accessFile.seek(start);
- HttpURLConnection conn=(HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(5000);
- conn.setRequestMethod("GET");
- //指定行网络文件的某个区域下载数据(开始位置-结束位置)
- conn.setRequestProperty("Range", "bytes="+start+"-"+end);
- //请求某一段数据的话,请求码不是200,是206
- if(conn.getResponseCode()==206){
- InputStream instream=conn.getInputStream();
- byte [] buffer=new byte[1024];
- int len=0;
- while((len=instream.read(buffer))!=-1){
- accessFile.write(buffer,0,len);
- }
- accessFile.close();
- instream.close();
- }
- System.out.println("第"+(threadid+1)+"线程已经下载完成");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
package cn.deu.hpu.download; import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; public class MulThreadDownLoad { public static void main(String[] args) throws Exception{
String path="http://192.168.111.104:8080/web/gg.jpg";
new MulThreadDownLoad().download(path,3);
} /*下载文件
* path 网络文件路径
* */
public void download(String path,int threadsize)throws Exception{
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200){
//取得网络文件的长度
int length=conn.getContentLength();
File file=new File(getFilename(path));
//随机访问文件类(生成一个与网络文件长度相等的本地文件)
RandomAccessFile accessFile=new RandomAccessFile(file, "rwd");
accessFile.setLength(length);
accessFile.close(); //计算每条线程需要下载的数据量
int block=length%threadsize==0?length/threadsize:length/threadsize+1;
for (int threadid = 0; threadid< threadsize; threadid++) {
new DownloadThread(threadid,block,url,file).start();
}
}else{
System.out.println("下载失败!");
} } private String getFilename(String path) {
//从URL地址的最后一个"/"后开始记录文件名
return path.substring(path.lastIndexOf("/")+1);
} private class DownloadThread extends Thread{
private int threadid;
private int block;
private URL url;
private File file;
public DownloadThread(int threadid,int block,URL url,File file){
this.threadid=threadid;
this.block=block;
this.url=url;
this.file=file;
} public void run(){
//计算该线程从网络文件的什么位置开始下载
int start=threadid*block;
//下载到网络文件的什么位置结束
int end=(threadid+1)*block-1;
try {
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
//从某一个位置开始写入数据
accessFile.seek(start);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//指定行网络文件的某个区域下载数据(开始位置-结束位置)
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
//请求某一段数据的话,请求码不是200,是206
if(conn.getResponseCode()==206){
InputStream instream=conn.getInputStream();
byte [] buffer=new byte[1024];
int len=0;
while((len=instream.read(buffer))!=-1){
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();
}
System.out.println("第"+(threadid+1)+"线程已经下载完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
转载请注明出处!程序猿之洞:http://blog.csdn.net/acmman
【转】【JAVA应用】多线程断点下载的更多相关文章
- Java实现多线程断点下载(下载过程中可以暂停)
线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...
- Java之多线程断点下载的实现
RandomAccessFile类: 此类的实例支持对随机訪问文件的读取和写入.随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组.光标或索引,称为文件指针.输入操 ...
- Android(java)学习笔记216:多线程断点下载的原理(Android实现)
之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...
- Android(java)学习笔记159:多线程断点下载的原理(Android实现)
之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...
- java多线程断点下载原理(代码实例演示)
原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...
- andoid 多线程断点下载
本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...
- 我的Android进阶之旅------>Android基于HTTP协议的多线程断点下载器的实现
一.首先写这篇文章之前,要了解实现该Android多线程断点下载器的几个知识点 1.多线程下载的原理,如下图所示 注意:由于Android移动设备和PC机的处理器还是不能相比,所以开辟的子线程建议不要 ...
- iOS开发网络篇—大文件的多线程断点下载
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...
- iOS开发网络请求——大文件的多线程断点下载
iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...
- iOS开发网络篇—大文件的多线程断点下载(转)
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...
随机推荐
- 文本可视化[二]——《今生今世》人物关系可视化python实现
文本可视化[二]--<今生今世>人物关系可视化python实现 在文本可视化[一]--<今生今世>词云生成与小说分析一文中,我使用了jieba分词和wordcloud实现了,文 ...
- [Python] 文科生零基础学编程系列三——数据运算符的基本类别
上一篇:[Python] 文科生零基础学编程系列二--数据类型.变量.常量的基础概念 下一篇: ※ 程序的执行过程,就是对数据进行运算的过程. 不同的数据类型,可以进行不同的运算, 按照数据运算类型的 ...
- Spring事务的传播行为和隔离级别
事物注解方式: @Transactional [一]传播行为: 使用方法:@Transactional(propagation=Propagation.REQUIRED) Require:支持当前事务 ...
- 数据帧CRC32校验算法实现
本文设计思想采用明德扬至简设计法.由于本人项目需要进行光纤数据传输,为了保证通信质量要对数据进行校验.在校验算法中,最简单最成熟的非CRC校验莫属了. 得出一个数的CRC校验码还是比较简单的: 选定一 ...
- 【HDFS】相关概念及常用命令
本文用于记录Hadoop中HDFS相关概念以及常用命令,以便日后查询. 概念之间无先后顺序,只是用于记录. 参考的Hadoop的版本是2.7.3 1. 角色 hadoop fs [hdfs dfs] ...
- Unity3D手机斗地主游戏开发实战(01)_发牌功能实现
园子荒废多年,闲来无事,用Unity3D来尝试做一个简单的小游戏,一方面是对最近研究的Unity3D有点总结,一方面跟广大的园友相互学习和提高.话不多说,进入正题~ 一.创建项目 1.创建Unity2 ...
- A Very Simple Problem
A Very Simple Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- python 进程池(multiprocessing.Pool)和线程池(threadpool.ThreadPool)的区别与实例
一般我们是通过动态创建子进程(或子线程)来实现并发服务器的,但是会存在这样一些缺点: 1.动态创建进程(或线程)比较耗费时间,这将导致较慢的服务器响应. 2.动态创建的子进程通常只用来为一个客户服务 ...
- JDBC+Servlet+jsp(增删查改)
先在mysql新增数据库和表先,把下面的几句代码复制去到mysql运行就可以创建成功了! 创建数据库 create database jdbc01 character set utf8 collat ...
- R-CNN论文翻译——用于精确物体定位和语义分割的丰富特征层次结构
原文地址 我对深度学习应用于物体检测的开山之作R-CNN的论文进行了主要部分的翻译工作,R-CNN通过引入CNN让物体检测的性能水平上升了一个档次,但该文的想法比较自然原始,估计作者在写作的过程中已经 ...