这篇博客就是接在我上篇博客网络编程–JAVA之多线程下载的基础上来实现的。

首先,我来说一下断点续存能解决啥问题

   假如当我们在进行MP4下载时,如果突然出现人为的中断或者意外的中断,那么当我们再次点击下载时,我们是希望下载的进度是接着上次中断的地方继续下载,而不是又重新的下载,这不是我们所希望的,那么断点续存就是解决这个问题的。

接着,我们还是来梳理一下断点续存的思路步骤:

  1. 要想继续在中断的位置继续下载,那么我们就得先记录下每条线程在中断时下载长度,而我们又不能判断出什么时候中断,所以我们就得时刻的将每条线程下载的长度及记录下来。

    (在这里,假如这里还是有三条线程A、B、C来进行分段的下载MP4,突然,一部小网断了,下载中断了,A线程在1的地方中断了,B线程在2的地方中断了,C线程在3的地方中断了,那么要想实现续存,就得知道1、2、3这三点时A、B、C上阴影部分的长度)

    2.完成下载后,我们为了不影响用户的内存以及保证用户不删错东西,我们要将保存每条线程长度的临时文件删除,作为一个完美的善后工作。


在这里的Main方法中,我们还是基本沿用了上篇博客 网络编程–JAVA之多线程下载上的Main方法的代码,只是加了一行代码:public static int finishedThead=0;(这是为了标志记录已经下载完成的线程,是为了后面的善后工作,也就是为了当全部完成后删除那些记录每条线程下载长度的临时文件),所以这里的Main方法中的代码就不写了。我们主要的操作是在DownLoadThread这个方法中的:


DownLoadThread代码块:

package com.ecjtu.mutilThread;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;/** 在这里我们是先完成多线程下载,再在此基础上添加少许代码完成断点续存*/
public class DownLoadThread extends Thread {private int startIndex,endIndex,threadId;private String path;public DownLoadThread(int startIndex,int endIndex,String path,int threadId) {this.startIndex=startIndex;this.endIndex=endIndex;this.path=path;this.threadId=threadId;}@Overridepublic void run() {URL url;try {///---------------------------------------------////这写代码也是断点续存添加的代码File file2=new File(threadId+".txt");int lastProgress=0;///这里是先判断临时文件是否存在,如果存在,将上次下载的最后进度读出来,并且加上startIndex///以此保证断点恢复后开始下载的位置是上次中断前的位置if(file2.exists()){FileInputStream fileInputStream=new FileInputStream(file2);BufferedReader br=new BufferedReader(new InputStreamReader(fileInputStream));lastProgress=Integer.parseInt(br.readLine());startIndex+=lastProgress;}///-------------------------------------------- ///这里才是利用HttpURLConnection拿到需要下载的真正的输入流url=new URL(path);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);///在这里用HttpURLConnection的设置请求属性的方法,来请求获取每一段的信息///在这里的格式书写是一样的,固定的。connection.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);///这里的206是代表上面的区段请求的响应的返回码if(connection.getResponseCode()==206){///接下就是输入流的一些操作InputStream is=connection.getInputStream();File file=new File("nihao.zip");RandomAccessFile ref=new RandomAccessFile(file,"rwd"); ref.seek(startIndex);///标志开始位置,可以让线程在文件中从不同位置开始存储byte[] b=new byte[1024];int len=0;int total = lastProgress;//注意这里需要改变一下,才能完整的实现断点续存while((len=is.read(b))!=-1){ref.write(b, 0, len);total+=len;System.out.println("第"+threadId+"条线程的下载"+total);///断点续存的添加代码///这段代码是将每个线程的Id的下载进度total记录保存为文件//--------------------------------------------------RandomAccessFile refprgrass=new RandomAccessFile(file2, "rwd");refprgrass.write((total+"").getBytes());refprgrass.close();//------------------------------------------------}ref.close();System.out.println("第"+threadId+"条线程的下载结束");///------------------------------------/** 这里代码也是断点续存增加的代码,* 在这里用一个标志位保证线程全部下载完成,才能让其删除临时文件* 如果在这里不用标志位来保证线程全部的下载完成的话再删除,而是当一条线程一下载完后就删除了的话,* (在这里假设线程A刚被下载完就存储下载长度的临时文件就被删除,)* 那么接着一旦中断,等到下次恢复时,那么线程A的临时存储的下载完成进度的文件没有了,被删掉了,但是其他线程因为没下完那些存储下载进度的文件还在,那这样就又会默认的重新的又将线程A重新的下载*/     Main.finishedThead++;///这就是上面说的善后的工作if(Main.finishedThead==Main.threadCount){///线程全都下完了for(int i=0;i<Main.threadCount;i++){File f=new File(i+".txt");//这里就是要用这种方式来找到那些临时文件进行一一的删除操作f.delete();///将新建的临时文件一一删除}}///----------------------------------------------}} catch (MalformedURLException e) {e.printStackTrace();} catch (ProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}super.run();}
}

在代码中,我将后面断点续存添加的代码分割出来并注释了,到了现在断点续存就完成了,但是在写完后我发现这里还是有一点的小瑕疵,那就是我们也应该将Main.finishedThead这个记录下载完成的线程个数放在文本中先保存下来,因为有可能出现当我们线程A线程B下完了,又来一个突然,断网了,中断了,那么当重新运行时,Main.finishedThead又被初始化为0,那么当线程C被下载完后,Main.finishedThead才变为1,这样就永远不可能等于线程的总数,也就不能将那些临时文件删掉了。总之一句话就是在这我们需要将Main.finishedThead保留成不管怎么中断,Main.finishedThead的值会一直稳定的+1,而不是中断了就又变为0,这里我就不写了,和将每个线程的下载长度保留的方法是一样的。

网络编程--JAVA之多线程下载后续:断点续存相关推荐

  1. java简单实现在线资源多线程下载,断点续存,限制最大正在下载数

    为什么要使用多线程下载,断点续存,限制最大正在下载数 多线程下载已经提高了下载的效率,但是当一些特殊情况发生的时候,我们需要对程序进行处理,这样效率会更高.比如,断电断网等造成下载中断,那么我们下一次 ...

  2. Python Tkinter 下载器 多任务下载+多线程下载+多任务断点续存

    功能介绍: 这次的下载器特点:多线程下载 + 多任务下载 + 多任务断点续存 视频演示: Python Tkinter 系列 - 下载器 界面: 轮子 文件大小 界面:Tkinter 下载功能 :re ...

  3. 网络编程学习(10)/ FTP项目(4) ——文件下载和下载断点续存功能

    网络编程学习(10)/ FTP项目(4) --文件下载和下载断点续存功能 服务端 `lib 文件夹下 main.py` 客户端 `client文件夹下 FTPClient.py 代码 interact ...

  4. java获取主机信息大全,网络编程:Java获取网络主机信息

    java.net.InetAddress类表示互联网协议 (IP) 地址. 有两个子类:Inet4Address, Inet6Address 通过 InetAddress可以方便获取一个域名下的IP, ...

  5. 网络编程学习(11)/ FTP项目(5) ——文件上传和上传断点续存功能

    网络编程学习(11)/ FTP项目(5) --文件上传和上传断点续存功能 `服务端 lib 文件夹下的 main.py 状态码的变化` 文件上传功能 `服务端 lib 文件夹下的 main.py` ` ...

  6. JAVA 实现多线程下载大文件

    JAVA 实现多线程下载大文件 开发中遇到一个问题,下载大文件到本地,导致等待时间过长,然后就寻找一个可以多线程下载的办法,受下载软件启发,想到多线程下载, 原理,首先查到这个文件的大小,然后根据线程 ...

  7. Python机器学习-搭建神经网络以及数据集引入和断点续存

    前言 本文旨在通过Python编程角度进行机器学习神经网络的引导,需要掌握基础的全连接神经网络基础,这包括了神经网络全连接层的结构,权重模板与偏置的作用,节点的处理方法.在掌握这些知识之后,本文将从代 ...

  8. python 保存数据单文件_python3.6 单文件爬虫 断点续存 普通版 文件续存方式

    #导入必备的包#本文爬取的是顶点小说中的完美世界为列.文中的aa.text,bb.text为自己创建的text文件 importrequestsfrom bs4 importBeautifulSoup ...

  9. python3.6怎么保存_python 保存数据单文件_python3.6 单文件爬虫 断点续存 普通版 文件续存方式...

    #导入必备的包#本文爬取的是顶点小说中的完美世界为列.文中的aa.text,bb.text为自己创建的text文件 importrequestsfrom bs4 importBeautifulSoup ...

最新文章

  1. 《流浪地球》虽好,却存在一个不可回避的硬伤!
  2. 没看过这条鄙视链,别轻易说你懂区块链!
  3. 【Python】深入理解Python函数的9个黄金法则
  4. 字典树(Trie)的java实现
  5. mobile cpu上禁用alpha test的相关总结
  6. web高德maker动画_Web Maker —我如何构建一个快速的离线前端游乐场
  7. leadshop开源商城系统
  8. 数字滤波器(二)--最小相位延时系统和全通系统
  9. 为什么要使用Elasticsearch?
  10. ActiveMQ学习总结(1)——ActiveMQ快速入门
  11. java和scala_什么是Scala及它与Java的区别
  12. EMNLP'21 Oral | 拓展你的视野!UCLA提出:地区多样性视觉常识推理
  13. php html页面显示乱码怎么解决方法,html网页乱码原因以及解决办法
  14. 【Android】安卓开发中的MVP架构模式与应用实例
  15. 关于坐标系的那些事-------------扯一扯坐标系的理论知识
  16. [转]file_get_contents(php://input)
  17. vue中nextTick的实际应用
  18. ESP32基于arduino开发的心跳体温检测系统(二)传感器的使用
  19. heavy r.com index.php,AngularJS - Computation-Heavy Tasks
  20. 20189220 余超《Linux内核原理与分析》第六周作业

热门文章

  1. 颜色转换助手RGB888-565
  2. 如何修改Nintendo Switch Dock以获得更好的便携性
  3. 几款常用装机检测软件
  4. sqlite 数据库连接问题以及解决方法
  5. 教你购物只花一半钱,先领优惠券再购物,原来你一直都买贵了?
  6. Git - 学习/实践 - 以及相关操作
  7. Ubuntu 18.04刷机问题汇总
  8. 高效便捷组卷功能,学练考一体化让考试更轻松
  9. HN2015集训 永远亭的竹笋采摘
  10. 搭建邮件群发服务器费用,自建邮件群发服务器优缺点分析