断点续传的原理:
把一个文件分为n个小文件,程序分n个线程去下载每一个小文件。阅读有关资料,IE浏览器传递给服务端的时候可以传递一个请求信息"Range":如:RANGE: bytes=2000070- 一看就知道告诉服务器下载的时候从2000070字节开始下载。值得注意的是response.getResponseCode()为206,不再是200了。
上代码:
/** * 下载工具类 * * @author aokunsang * */ public class FileDownloader { private HttpURLConnection conn; public static void main(String[] args) throws Exception { FileDownloader load = new FileDownloader(); load.download(); } /** * 开始下载 */ public void download() throws Exception { HttpConnect connect = new HttpConnect(1); int fileSize = 0, threadSize = 3; // 文件长度和线程数 conn = connect.initConnction(); conn.connect(); if (conn.getResponseCode() == 200) { fileSize = conn.getContentLength(); conn.disconnect(); } int perthThreadSize = fileSize / 3 + 1; //每个线程需要下载的文件大小 RandomAccessFile raf = new RandomAccessFile(new File("D://ca.mp3"), "rw"); raf.setLength(fileSize); raf.close(); long startTime = System.currentTimeMillis(); for (int i = 0; i < threadSize; i++) { int startpos = i * perthThreadSize; //线程开始下载的位置 RandomAccessFile raff = new RandomAccessFile(new File("D://ca.mp3"), "rw"); raff.seek(startpos); new myThread(startpos, perthThreadSize, i, raff).start(); } long endTime = System.currentTimeMillis(); while(Thread.activeCount()>1){} //防止main线程结束而导致下载线程被销毁 System.out.println("--------------下载完成,共耗时:"+(endTime-startTime)/(60*1000)+"分钟--------"); } class myThread extends Thread { private int startpos; private int perThreadSize; private int threadId; private RandomAccessFile raf; public myThread(int startpos, int perThreadSize, int threadId, RandomAccessFile raf) { this.startpos = startpos; this.perThreadSize = perThreadSize; this.threadId = threadId; this.raf = raf; } @Override public void run() { HttpConnect connect = new HttpConnect(0); HttpURLConnection con = connect.initConnction(); con.setRequestProperty("Range", "bytes=" + this.startpos + "-"); try { InputStream is = con.getInputStream(); byte[] bt = new byte[1024]; int length = 0; int len = 0; while (length < this.perThreadSize && (len = is.read(bt)) != -1) { raf.write(bt, 0, len); length += len; } raf.close(); is.close(); System.out.println("线程"+threadId+"完成!"); } catch (Exception e) { e.printStackTrace(); } } } class HttpConnect { private int flag; public HttpConnect(int flag) { this.flag = flag; } public HttpURLConnection initConnction() { HttpURLConnection connection = null; try { URL url = new URL(HttpConnectParams.URLSTRING.content); connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(Integer .parseInt(HttpConnectParams.CONNECTTIEMEDOUT.content)); connection.setRequestMethod(HttpConnectParams.POST.content); connection.setRequestProperty(HttpConnectParams.ACCECT.header, HttpConnectParams.ACCECT.content); connection.setRequestProperty( HttpConnectParams.ACCECT_LANGAGE.header, HttpConnectParams.ACCECT_LANGAGE.content); connection.setRequestProperty(HttpConnectParams.CHARSET.header, HttpConnectParams.CHARSET.content); if (flag == 1) { connection.setRequestProperty( HttpConnectParams.KEEPCONNECT.header, HttpConnectParams.KEEPCONNECT.content); } } catch (Exception e) { connection = null; } return connection; } } }
一/**
* HTTP请求的一些常量信息 * @author aokunsang * */ public enum HttpConnectParams { /** * URL地址(mp3格式的音乐文件) */ URLSTRING("http://www.61mp3.cn/music/%B6%F9%CD%AF%B8%E8%C7%FA/%CA%AE%B6%FE%C9%FA%D0%A4%B8%E8.mp3"), /** * 请求的方式 */ POST("GET"), /** * 请求的格式 */ ACCECT("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"), /** * 请求的语言 */ ACCECT_LANGAGE("Accept-Language","zh-CN"), /** * 请求的字符集编码 */ CHARSET("Charset","UTF-8"), /** * 链接的超时数 */ CONNECTTIEMEDOUT("5000"), /** * 保持链接 */ KEEPCONNECT("Connection","Keep-Alive"); public String header; //标题 public String content; //内容 private HttpConnectParams(String header,String content) { this.header = header; this.content = content; } private HttpConnectParams(String content){ this.content = content; } }
相关推荐
Android 进行文件分段多线程下载的实例,用户可以指定线程数,还可以通过进度条查看下载的进度。
新鲜出炉的SpringBoot版本的多线程下载文件,可以拿来整合SpringBoot项目或者SSM项目,可直接运行测试!!!
纯JavaFX实现的多线程分段下载工具,不依赖任何第三方库,实现多线程分段下载以及下载完成后的资源合并,全图形化界面操作,充分利用多核CPU。
用socket实现了多线程多服务分段(断点)下载同一个文件,大大地提高了文件的下载速度,也可以断点。
这是一个在listview或gridview中选项同时分别下载文件的demo。 每个选项进度条分别更新进度。
1.创建多线程程序 2.使用RandomAccessFile类分段读写大文件 3.通过多线程分段读取大文件并分段写入到新文件
JAVA代码实现多线程分段下载+断点续传 原理很清楚,但是其中涉及到几个关键的问题: 1.需要请求的数据如何分段。 2.分段下载的数据如何组装成完整的数据文件。 3.断点的数据如何保存,再次下载如何继续上次保存的...
FTP多线程上传下载、断点续传、分段下载--田景吉之C#版本
项目中用到分段文件下载,也使用多线程下载,提高下载效率。 自己花了时间整合成一个项目,可直接执行Junit方法看效果。
代码作用:多线程分段下载,加快下载速度,加入适当代码可支持断点下载 ================================================= ·示例代码位置: [项目目录]/src-app/app/DownloaderApp.java 代码里写了注释,有一定...
想要下载国外的一些视频速度太慢所以自己写了一个工具,利用多线程分段下载单个资源,并且使用5秒的TimeOut以及二十次的重试次数达到高速下载的目的,实测有效,下载某MMD网站的资源速度从20kb/s提升到了300kb/s,...
Delphi线程池实现多线程FTP分段下载组件 by :renshouren mail:114032666@qq.com QQ:114032666 2019.10.05 使用的组件 1、TIdFTP Indy FTP客户端 2、TThreadsPool 线程池 工作原理及流程 调用本单元,将自动在程序...
刚学完多线程和线程池,以及线程爱好者。 使用场景及目标: 大文件的快速下载,经测试在100M带宽的网络下,下载一个40M的文件,不超过两秒钟,当然还得根据自己电脑的配置来讲。 其他说明: 文件如果特别小,而...
单、多线程断点续传下载 单、多线程断点续传下载 压缩包里面有截图和apk
C#写的,可以多线程传输文件,多线程断点续传文件
主要为大家详细介绍了java使用多线程读取超大文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Java 多线程断点下载文件基本原理:利用URLConnection获取要下载文件的长度、头部等相关信息,并设置响应的头部信息,本文将详细介绍,需要了解更多的朋友可以参考下
多线程网络传输大都没有实现大于2G文件,在前人基础上改写的真正的多线程网络传输,不受文件大小的限制!先上传大文件上传的完整代码,有需要大文件超过2G的下载,请留言!
自己写的Android多线程多任务断点下载的一个Demo。 1.通过Service和线程池配合控制下载任务(包含分段下载)的开始和暂停; 2.通过数据库对文件信息以及下载线程信息进行保存,实现断点下载。 有发现的bug希望各路坛...
多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,每个线程只负责下载其中的一部分,最后将每一个线程下载的部分组装起来即可。...