RandomAccessFile类:
此类的实例支持对随机訪问文件的读取和写入。随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组。

存在指向该隐含数组。光标或索引,称为文件指针。输入操作从文件指针開始读取字节。并随着对字节的读取而前移此文件指针。

假设随机訪问文件以读取/写入模式创建,则输出操作也可用。输出操作从文件指针開始写入字节。并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针能够通过 getFilePointer 方法读取。并通过 seek 方法设置。

以下有RandomAccessFile实现安卓下的断点下载的demo。

server端能够用tomcat模拟。将被下载的測试文件放入webApp/ROOT文件夹下就可以。
先给出java借助HttpURLConnection类实现的多线程下载代码:

public class MultiThread {private static int threadCount = 3;private static long blockSize;private static int runningThreadCount;public static void main(String[] args) throws Exception {String path = "http://10.0.67.172/test.exe";URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);//超时时间int code = conn.getResponseCode();System.out.println(code);if(code / 100 == 2){int size = conn.getContentLength();//获取资源文件的长度System.out.println("请求资源大小:" + size);blockSize = size / threadCount;//将资源文件分为多少块。没一块的大小runningThreadCount = threadCount;long startIndex = 0;long endIndex = 0;//开启若干个子线程去实现多线程的下载for(int i = 0; i < threadCount; i++){startIndex = i * blockSize;endIndex = (i + 1) * blockSize - 1;if(i == threadCount-1){endIndex = size - 1;}System.out.println("开启线程:" + i + ";" + "開始位置:" + startIndex + ":" + "结束位置:" + endIndex);new DownThread(path, startIndex, endIndex, i).start();}}}private static class DownThread extends Thread{private String path;private long startIndex;private long endIndex;private int threadId;public DownThread(String path, long startIndex, long endIndex, int threadId) {super();this.path = path;this.startIndex = startIndex;this.endIndex = endIndex;this.threadId = threadId;}@Overridepublic void run() {try {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setReadTimeout(5000);conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//设置server上的文件的读取位置int code = conn.getResponseCode();if(code / 100 == 2){InputStream is = conn.getInputStream();File file = new File("temp.exe");RandomAccessFile raf = new RandomAccessFile(file, "rw");raf.seek(startIndex);System.out.println("第" + threadId + "个文件的開始位置:" + String.valueOf(startIndex));int len = 0;byte[] buffer = new byte[1024];while ((len = is.read(buffer)) != -1){raf.write(buffer, 0, len);//写文件}raf.close();}} catch (Exception e) {e.printStackTrace();}}}
}

断点下载的原理就是将上次文件下载的位置保存为暂时文件,当全然完成下载时再删除。

public class MultiThread {private static int threadCount = 3;private static long blockSize;private static int runningThreadCount;public static void main(String[] args) throws Exception {String path = "http://10.0.67.172/test.rar";URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);//超时时间int code = conn.getResponseCode();System.out.println(code);if(code / 100 == 2){int size = conn.getContentLength();//获取资源文件的长度System.out.println("请求资源大小:" + size);blockSize = size / threadCount;//将资源文件分为多少块,没一块的大小runningThreadCount = threadCount;long startIndex = 0;long endIndex = 0;for(int i = 0; i < threadCount; i++){startIndex = i * blockSize;endIndex = (i + 1) * blockSize - 1;if(i == threadCount-1){endIndex = size - 1;}System.out.println("开启线程:" + i + ";" + "開始位置:" + startIndex + ":" + "结束位置:" + endIndex);new DownThread(path, startIndex, endIndex, i).start();}}}private static class DownThread extends Thread{private String path;private long startIndex;private long endIndex;private int threadId;public DownThread(String path, long startIndex, long endIndex, int threadId) {super();this.path = path;this.startIndex = startIndex;this.endIndex = endIndex;this.threadId = threadId;}@Overridepublic void run() {int total = 0;try {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 reader = new BufferedReader(new InputStreamReader(fis));//获取当前线程上次下载的总大小是多少String lasttotalstr = reader.readLine();int lastTotal = Integer.valueOf(lasttotalstr);System.out.println("上次线程下载的总大小:" + lastTotal);startIndex += lastTotal;total += lastTotal;fis.close();}conn.setReadTimeout(5000);conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//设置server上的文件的读取位置int code = conn.getResponseCode();if(code / 100 == 2){InputStream is = conn.getInputStream();File file = new File("temp.rar");RandomAccessFile raf = new RandomAccessFile(file, "rw");raf.seek(startIndex);System.out.println("第" + threadId + "个文件的開始位置:" + String.valueOf(startIndex));int len = 0;byte[] buffer = new byte[1024];while ((len = is.read(buffer)) != -1){RandomAccessFile rf = new RandomAccessFile(positionFile, "rwd");raf.write(buffer, 0, len);//写文件total += len;rf.write(String.valueOf(total).getBytes());rf.close();}is.close();raf.close();}} catch (Exception e) {e.printStackTrace();}finally{synchronized (DownThread.class) {System.out.println("线程" + threadId + "完成下载了");runningThreadCount--;if (runningThreadCount < 1) {System.out.println("全部的线程都工作完成了。删除暂时记录的文件");for (int i = 0; i < threadCount; i++) {File f = new File(i + ".txt");System.out.println(f.delete());}}}}}}
}

执行结果截图:

转载于:https://www.cnblogs.com/yxwkf/p/5303691.html

Java之多线程断点下载的实现相关推荐

  1. Java简单多线程断点下载

    使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多.如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行 ...

  2. Java多线程断点下载

    多线程下载已经提高了下载的效率,但是当一些特殊情况发生的时候,我们需要对程序进行处理,这样效率会更高.比如,断电断网等造成下载中断,那么我们下一次又要重新开始下载,这样效率底下,所以我们可以考虑使用断 ...

  3. android 多线程断点下载,listview 模式 开始 暂停等功能

    android 多线程断点下载,listview 模式 代码依次如下: 布局: <?xml version="1.0" encoding="utf-8"? ...

  4. 安卓客户端的多线程断点下载(SharedPreferences版)

    题记:从百度百科上面我们知道,SharedPreferences是不支持多线程的,但是这次使用SharedPreferences实现了多线程断点下载.点解? 服务器端: 使用的是tomcat服务器,在 ...

  5. 即拿即用-Android多线程断点下载

    线程下载只需要确定好下载一个文件需要多少个线程,一般来说最好为3条线程,因为线程过多会占用系统资源,而且线程间的相互竞争也会导致下载变慢. 其次下载的时候将文件分割为三份(假设用3条线程下载)下载,在 ...

  6. iOS开发网络篇—多线程断点下载

    iOS开发网络篇-多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  7. android学习笔记---31_多线程断点下载器,下载原理实现

    1.1.31_多线程断点下载器 ----------------------- 1.软件界面:   文件下载路径              text框   button 下载   点击后,下面显示下载 ...

  8. java 下载暂停实现_Java实现多线程断点下载(下载过程中可以暂停)

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...

  9. Java使用HttpUrlConnection实现多线程断点下载

    相信很多同学在面试的时候,经常会被面试官问到这么一个问题:请问如何实现断点下载,即在文件未下载完成时,保存进度,在下次继续下载.要实现这个功能其实并不难,只要使用一个临时文件记录当前的下载进度,然后在 ...

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

    1. 为什么需要多线程下载?     服务器的资源有限,同时的平均地分配给每个客户端.开启的线程越多抢占的服务的资源就越多,下载的速度就越块. 2. 下载速度的限制条件? (1)你的电脑手机宽带的带宽 ...

最新文章

  1. 2017 年已读书单总结
  2. 摸透 Redis 主从复制、哨兵、Cluster 三种模式
  3. 课时55.详情和概要标签(理解)
  4. Spring Boot Initilizr Web界面
  5. win10开移动热点让手机使用上网
  6. JavaScript数组操作 [Z]
  7. Linux下 Mysql 命令 备份
  8. Python——EM(期望极大算法)实战(附详细代码与注解)(一)
  9. 59道CSS面试题(附答案)
  10. eNSP路由器启动不了
  11. [JZOJ3385] [NOIP2013模拟] 黑魔法师之门 解题报告(并查集)
  12. matlab曲线拟合工具箱 cftool
  13. netbean 偶尔无法设置断点问题
  14. 流行的蓝光影片播放器推荐
  15. 基于 STM32F103C8T6 对音频数据的 Flash 读取与 DAC 播放
  16. 欧菲光净利暴跌,提醒了中国制造,原来苹果如此重要
  17. python3 案例分享-seaborn demo
  18. 更新数据时,MySQL的聚簇索引是如何变化的?
  19. JSP、Servlet+MySQL线上网上图书商城书城书店系统平台课程设计JQuery
  20. arcgis 合并名字相同的要素_ArcGIS中各种合并要素异同

热门文章

  1. CS224N笔记——TensorFlow入门
  2. 《python 编程从入门到实践》变量
  3. 【289天】每日项目总结系列027(2017.11.21)
  4. C# 使用SqlDataReader方式使用数据做查询的例子
  5. Cobbler-自动化部署神器01
  6. bash脚本编程之十 函数
  7. C#基础-Func,Action
  8. [经典php视频]构建正则表达式解析网页中的图像标记img
  9. 本地上支持apache多站点访问
  10. 主机动手系列 — 不同CPU,不同命令,怎么管理HP-UX服务器