断点续传:将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度。


RandomAccessFile的四种传输模式

  • r 以只读的方式打开文本,也就意味着不能用write来操作文件
  • rw 读操作和写操作都是允许的
  • rws 每当进行写操作,同步的刷新到磁盘,刷新内容和元数据
  • rwd 每当进行写操作,同步的刷新到磁盘,刷新内容

断点续传实现思路:将大文件均分成几块后,每个线程分别处理一块数据的读取和写入。每次写入都要更新记录的日志文件,断网或暂定后重新开始传输时,根据日志文件的信息,可以接着读取写入数据,不用重头开始传输

代码如下(多线程实现断点续传):

    /*** 断点续传** @param dataStr   目标文件地址* @param targetStr 存放地址*/public static void breakpointResume(String dataStr, String targetStr) {File dataFile = new File(dataStr);long length = dataFile.length();int threadNum = 4;//指定线程数//每个线程均分文件大小,且向上取整long part = (long) Math.ceil(length / threadNum);//线程减法计数器CountDownLatch countDownLatch = new CountDownLatch(threadNum);Instant beginTime = Instant.now();//记录传输的日志文件File logFile = new File(targetStr + ".log");String[] splitData = null;//不是null就需要断点续传BufferedReader reader = null;try {if (logFile.exists()) {//存在日志文件,需要进行断点续传reader = new BufferedReader(new FileReader(logFile));String data = reader.readLine();splitData = data.split(",");} else {//不存在日志文件,创建日志文件logFile.createNewFile();}Map<Integer, Long> maps = new ConcurrentHashMap<>();for (int i = 0; i < threadNum; i++) {final int k = i;System.out.println("线程正在执行任务:" + k);String[] finalData = splitData;new Thread(() -> {RandomAccessFile inFile = null;RandomAccessFile outFile = null;RandomAccessFile rafLog = null;try {inFile = new RandomAccessFile(dataFile, "r");//读outFile = new RandomAccessFile(targetStr, "rw");//写rafLog = new RandomAccessFile(logFile, "rw");//操作日志文件的流//确定每个线程读取文件的开始和结束的位置,有断点续传就从日志文件取出的位置开始读取inFile.seek(finalData == null ? k * part : Long.parseLong(finalData[k]));//设置每个线程读取的启始位置outFile.seek(finalData == null ? k * part : Long.parseLong(finalData[k]));//设置每个线程写入的启始位置byte[] bytes = new byte[1024 * 10];//每次读取字节大小int len = -1, allLen = 0;while (true) {len = inFile.read(bytes);//从磁盘读取到缓存if (len == -1) { //数据读完,结束break;}//如果不等于 -1,把每次读取的字节累加allLen = allLen + len;//将读取的字节数放入到map中maps.put(k, allLen + (finalData == null ? k * part : Long.parseLong(finalData[k])));//每个线程的绝对偏移量outFile.write(bytes, 0, len);//从缓存写入到磁盘//将map中的字节日志信息数据写入磁盘StringJoiner stringJoiner = new StringJoiner(",");maps.forEach((key, value) -> stringJoiner.add(String.valueOf(value)));//将日志信息写入磁盘rafLog.seek(0);//覆盖之前的日志信息rafLog.write(stringJoiner.toString().getBytes("UTF-8"));/*** 当前线程读取的内容*  allLen + (k * part)*  或*  allLen + finalData[k] 日志文件里面的偏移量*  >=*  下个线程的起始部分((k + 1) * part)*  当前线程就不再读取写入数据,结束任务*/if (allLen + (finalData == null ? k * part : Long.parseLong(finalData[k])) >= (k + 1) * part) {break;}}} catch (IOException e) {e.printStackTrace();} finally {//关流if (null != outFile && null != inFile && null != rafLog) {try {outFile.close();inFile.close();rafLog.close();} catch (IOException e) {e.printStackTrace();}}countDownLatch.countDown();//减一}}).start();}//主线程要等到线程计数器归零,再继续往下执行countDownLatch.await();Instant endTime = Instant.now();System.out.println("总耗时:" + (Duration.between(beginTime, endTime).toMillis()) + "毫秒");//删除日志文件logFile.delete();} catch (Exception e) {e.printStackTrace();} finally {if (null != reader) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}}

运行如下:

6个多G的资料  >_<
线程正在执行任务:0
线程正在执行任务:1
线程正在执行任务:2
线程正在执行任务:3
总耗时:60039毫秒

CPU 、内存、磁盘都被利用起来了:

内容转自B站up视频

JAVA多线程实现断点续传相关推荐

  1. java多线程下载_Java实现多线程下载,支持断点续传

    多线程下载及断点续传的实现是使用 HTTP/1.1 引入的 Range 请求参数,可以访问Web资源的指定区间的内容.虽然实现了多线程及断点续传,但还有很多不完善的地方. 包含四个类: Downloa ...

  2. java ftp 断点,java实现ftp断点续传

    //import cz.dhl.io.*; //import cz.dhl.ftp.*; import .ftp.*; import .*; import java.applet.*; import ...

  3. Java 服务器端支持断点续传的源代码

    2019独角兽企业重金招聘Python工程师标准>>> Java 服务器端支持断点续传的源代码[支持快车.迅雷](仅支持 HTTP 协议) 网上关于 Java 支持 HTTP 断点续 ...

  4. Android多线程下载断点续传

    先上图看卡结果: GITHUB:Android多线程下载断点续传 下载杵这儿 如图所示点击下载就开始下载,点击停止就会停止再次点击下载就会接着下载了. 设计思路是这样的: 首先通过广播将下载信息传递给 ...

  5. java多线程查询_java多线程查询

    标签: 由于最近工作遇到性能问题,尝试研究用多线程来实现,结果速度快了好几倍 下面是多线程查询的部分代码,提供给大家参考下: 线程类: 带返回值的类要实现Callable接口,具体业务逻辑没有实现,只 ...

  6. Java 服务器端支持断点续传的源代码【支持快车、迅雷】

    Java 服务器端支持断点续传的源代码[支持快车.迅雷](仅支持 HTTP 协议) 网上关于 Java 支持 HTTP 断点续传的文章不少,但关于 Java 服务器端支持 HTTP 断点续传的却比较少 ...

  7. java多线程下载源码_Java多线程文件分片下载实现的示例代码

    多线程下载介绍 多线程下载技术是很常见的一种下载方案,这种方式充分利用了多线程的优势,在同一时间段内通过多个线程发起下载请求,将需要下载的数据分割成多个部分,每一个线程只负责下载其中一个部分,然后将下 ...

  8. Java 多线程的基本方式

    Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):

  9. Java多线程读取本地照片为二进制流,并根据系统核数动态确定线程数

    Java多线程读取图片内容并返回 1. ExecutorService线程池 2. 效率截图 3. 源码 1. ExecutorService线程池 ExecutorService线程池,并可根据系统 ...

最新文章

  1. 《大话存储》读书笔记一
  2. 常用的图像增强处理办法
  3. python3 csv 读入数组_如何将CSV数据读入NumPy中的记录数组?
  4. mongodb php update,MongoDB文档的更新(php代码实例)
  5. sklearn 决策树例子_决策树--规则挖掘应用
  6. 美团信用卡现金分期怎么还?
  7. 由外而内看敏捷软件开发(上)——从业务视角看敏捷
  8. 纸筒制作机器人_趣味STEAM教育:如何用“垃圾”制作机器人?
  9. Visio绘制电路图
  10. HP服务器固件升级(ILO及bios升级:实操版)
  11. python 角度变弧度_弧度制和角度值怎么转换?
  12. hibernate 数据分页显示 及 分页导航栏的设置
  13. 软考嵌入式系统设计师
  14. 大数据是什么 有哪些价值
  15. rust倒地了怎么起来_ggxx出招表
  16. 成功解决http error 503.the service is unavailable错误
  17. 混沌工程:分布式系统稳定性的“疫苗”
  18. python 画心形线 matplotlib
  19. 服务器繁忙 微信 苹果,iOS 9正式放出 服务器繁忙苹果推荐用户早晨更新
  20. 太硬核了,我写了一份操作系统词典送给你!

热门文章

  1. 《炬丰科技-半导体工艺》湿法加工中掩模对准晶体方向的确定
  2. 关于开源的GIS现状分析
  3. 用limma包的voom方法来做RNA-seq 差异分析
  4. 基于PHP电影购票系统的设计与实现
  5. CleanMyMac X适用于Mac电脑安全的软件
  6. ups不间断电源高频机和工频机UPS不间断电源的比较
  7. 高仿微信上传头像附带压缩,旋转图片,附加demo
  8. n3k配置vpc是否还需要配置hsrp_HSRP协议详解:配置HSRP实现网关的冗余备
  9. dubbogo 回顾与展望
  10. 二十年后的回眸(9)——十年著书路