多线程分段下载文件

原理

先获取文件大小,然后分段分配任务给线程下载

在开始多线程下载前得先得知下载文件的大小,如果在之前的流程中并没有告知文件大小则可以使用HTTP请求方法 HEAD,这个请求方法类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头,在头部中可以找到字段content-length就是文件大小了。

得知文件长度后应分割需要下载的起止位置以便之后使用。
有具体位置后就可以启动多线程发送网络请求,在网络请求中使用HTTP协议的头部标志Range,这个标志的使用方法是Range:bytes=start-end。

实现

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;/*** Created with IntelliJ IDEA.** @Auther: zlf* @Date: 2021/09/14/1:01* @Description:*/
public class MutiThreadDownload {private int threadCount = 5; // 下载线程数private long blocksize; // 每线程下载区块大小private int runningThreadCount; // 正运行线程数public int getThreadCount() {return threadCount;}public void setThreadCount(int threadCount) {this.threadCount = threadCount;}public long getBlocksize() {return blocksize;}public void setBlocksize(long blocksize) {this.blocksize = blocksize;}public int getRunningThreadCount() {return runningThreadCount;}public void setRunningThreadCount(int runningThreadCount) {this.runningThreadCount = runningThreadCount;}/*** @Description: 多线程分段下载* @Param: [url, filePath]* @return: void* @Author: zlf* @Date: 2021/9/14*/public void download(String url, String filePath) throws IOException {HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();int code = conn.getResponseCode();if (code == 200) {long size = conn.getContentLength();// 文件大小blocksize = size / threadCount;// 1.创建RandomAccessFile文件(可以随机访问)RandomAccessFile raf = new RandomAccessFile(new File(filePath), "rw");raf.setLength(size);// 2.多线程下载对应区块runningThreadCount = threadCount;for (int i = 1; i <= threadCount; i++) {long startIndex = (i - 1) * blocksize;long endIndex = i * blocksize - 1;if (i == threadCount) {endIndex = size - 1;}new DownloadThread(i, url, filePath,startIndex, endIndex).start();}}conn.disconnect();}/**** @Description: 分段下载的线程* @Param: * @return: * @Author: zlf* @Date: 2021/9/14*/private class DownloadThread extends Thread {private int id;private String url;private long startIndex;private long endIndex;private String filePath;public DownloadThread(int id, String url, String filePath, long startIndex, long endIndex) {this.id = id;this.url = url;this.startIndex = startIndex;this.filePath = filePath;this.endIndex = endIndex;}@Overridepublic void run() {try {HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();conn.setRequestMethod("GET");// 1.读取文件断点位置curIndexint curIndex = 0;File indexFile = new File("indexFile_"+id);if (indexFile.exists() && indexFile.length() > 0) {FileInputStream fis = new FileInputStream(indexFile);BufferedReader br = new BufferedReader(new InputStreamReader(fis));curIndex = Integer.valueOf(br.readLine());startIndex += curIndex;fis.close();}// 2.从startIndex位置下载文件, 并从startIndex位置写入raf文件conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);InputStream is = conn.getInputStream();RandomAccessFile raf = new RandomAccessFile(new File(filePath), "rw");raf.seek(startIndex);int len = 0;byte[] buffer = new byte[1024*1024];while ((len = is.read(buffer)) != -1) {raf.write(buffer, 0, len);// 更新断点位置RandomAccessFile indexRaf = new RandomAccessFile(indexFile, "rwd");curIndex += len;indexRaf.write(String.valueOf(curIndex).getBytes());indexRaf.close();}is.close();raf.close();} catch (Exception e) {e.printStackTrace();} finally {// 3.所有线程下载完,删除断点位置文件indexFilesynchronized (MutiThreadDownload.class){if (--runningThreadCount == 0) {for (int i = 1; i <= threadCount; i++) new File("indexFile_"+i).delete();}}}}}public static void main(String[] args) throws IOException {MutiThreadDownload mutiThreadDownload = new MutiThreadDownload();mutiThreadDownload.setRunningThreadCount(5);mutiThreadDownload.download("http://img.netbian.com/file/2020/0904/de2f77ed1090735b441ba5e4c2b460ca.jpg","D:/a.jpg");}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玛酷机器人课程视频_建阳玛酷机器人丨2019WRO机器人比赛凯旋而归!

2019年7月福州WRO青少年机器人交流RA 7月27-28日&#xff0c;经过角逐&#xff0c; WRO华南赛区(福州站)在福州中加学校顺利落幕。 本次大赛设置了山火营救、无人速递、城市救援、RA常规赛、足球世界杯、WEDO常规项目、WEDO小手拼出大世界等七个单项比赛。 …

kindeditor图片批量上传失败问题

2019独角兽企业重金招聘Python工程师标准>>> 问题&#xff1a;在演示版中批量上传没有问题&#xff0c;放到我们后台系统中&#xff0c;就上传不成功。 排查&#xff1a;逐步验证发现根本没有http到upload上传文件中&#xff0c;往上找。。。终于碰到是后台管理员验…

presto集群安装

presto集群安装 整合hive 张映 发表于 2019-11-07 分类目录&#xff1a; hadoop/spark/scala 标签&#xff1a;hive, presto Presto是一个运行在多台服务器上的分布式系统。 完整安装包括一个coordinator&#xff08;调度节点&#xff09;和多个worker。 由客户端提交查询&…

wps 复制流程图_简单三步,用WPS轻松完成一个又大气又好看的流程图!

流程图是工作中经常需要用到的图形&#xff0c;使用 WPS 可以方便地创建流程图。创建的流程图保存在云文档后&#xff0c;可以随时插入 WPS 的其他组件。新建流程图文件流程图可以从 WPS 的其他组件中创建&#xff0c;如 WPS 文字、WPS 表格等&#xff0c;也可以单独创建。流程…

CAS实现原子操作的三大问题

在Java中可以通过锁和CAS的方式实现原子操作。 CAS实现原子操作的三大问题 1.ABA问题 CAS需要在操作值的时候&#xff0c;检测值有没有发生变化&#xff0c;如果没有发生变化则更新。 但是如果一个值原来是A&#xff0c;变成B&#xff0c;又变成A&#xff0c;那么使用CAS进行…

Tez 0.9安装部署+hive on tez配置 + Tez-UI

Tez说明 将xyz替换为您正在使用的tez发行版号。例如0.5.0。对于Tez版本0.8.3和更高版本&#xff0c;Tez需要Apache Hadoop版本为2.6.0或更高版本。对于Tez版本0.9.0及更高版本&#xff0c;Tez需要Apache Hadoop版本为2.7.0或更高版本。 关于版本 1.Hadoop 2.7.0&#xff08;我…

iphone 字体

今天在网上找了下&#xff0c;iphone的UITextView字体类型的设置。现总结如下&#xff0c;如有误&#xff0c;欢迎指正。 [textView setFont:[UIFont fontWithName:"TrebuchetMS-Italic" size:18]];但是字体的类型名不好找&#xff0c;总结下有这么些类型&#xff1a…

启动成功浏览器显示不了_移动端利用chrome浏览器在PC端进行调试方法

由于最近工作中遇到需要在电脑上调试手机端的功能和样式&#xff0c;之前也没有遇到过&#xff0c;所以就各种百度和试验。最后终于功夫不负有心人&#xff0c;成功了。(那一刻心情真滴很鸡冻啊~~~~~~~~~)。所以暂时记录下来。以免鸡冻过度再给忘记了。好&#xff0c;接下来就是…

面向对象的相关面试题

1.面向对象的特征有哪些方面? 主要有封装,继承,多态,也可以加上个抽象. 封装 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响.在面对对象的编程语言中,对象是封装的最基本的单位,面向对象的封装比…

在maven本地仓库导入jar包

# Dfile jar包所在位置 DgroupId 指定groupId DartifactId 指定artifactId Dversion 指定版本 mvn install:install-file -DfileC:\Users\zlf\Desktop\mybatis-main\target\mybatis.jar -DgroupId"cn.bugstack.middleware" -DartifactIdmybatis -Dversion"1.0.…

Flink完全分布式集群安装

Flink支持完全分布式模式&#xff0c;这时它由一个master节点和多个worker节点构成。在本节&#xff0c;我们将搭建一个如下的三个节点的Flink集群。 一、Flink集群安装、配置和运行 Flink完全分布式集群搭建步骤如下&#xff1a; 1、配置从master到worker节点的SSH无密登录&…

一个4体低位交叉的存储器_前交叉韧带术后关节粘连的康复策略

ACL术后粘连的康复现状在国外&#xff0c;前交叉韧带ACL重建术后关节粘连的发生率为1%。在国内&#xff0c;由于多数医院在行前交叉韧带重建术后&#xff0c;对患者缺少及时、系统、科学的康复治疗&#xff0c;大部分患者由此易发生关节粘连&#xff0c;而往往关节粘连造成的功…

Maven多模块打包

在类似如下的场景中进行打包 lottery-rpc 将出现报错&#xff0c;原因是没办法将 lottery-common 一起打包进去。 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://…

hadoop 2.6.5 + hive 集群搭建

Hadoop 搭建&#xff1a;https://blog.csdn.net/sinat_28371057/article/details/109135056 hive 搭建 1. 系统环境 centos 7.3 Hadoop 2.7.3 jdk 1.8 MySQL安装在master机器上&#xff0c;hive服务器也安装在master上 hive版本: https://mirrors.cnnic.cn/apache/hive/hive…

光耦和开关频率

为什么80%的码农都做不了架构师&#xff1f;>>> TLP250&#xff0c;HCPL3120都可以 直接驱动小型IGBT&#xff0c;不需要加推挽管 6N137&#xff0c;没有推挽&#xff0c;OC上拉&#xff0c;到最后可能驱动速度还上不去 我们6N137&#xff0c;是用来驱动IPM的 电压…

配置babel_Babel 7 下配置 TypeScript 支持

本文将展示&#xff0c;如何使用 babel/preset-typescript 和 babel/preset-env 配置一个最小但完整的编译环境&#xff0c;打包工具使用 webpack4.41.2插件集 preset-typescriptpreset-typescript 是 Babel 提供的预设插件集之一&#xff0c;Babel 官方对其有一篇简短的介绍&a…

jQuery 计时器(jquery timers)简单应用

jquery timers 代码&#xff08;版本1.2&#xff09;&#xff1a; jquery timers /** * jQuery.timers - Timer abstractions for jQuery * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com) * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/). …

服务器改用ssh文件登录

首先在服务器生成密钥 ssh-keygen -t rsa -b 4096 将 id_rsa.pub的内容导入到 authorized_keys文件中&#xff0c;这样远程登录时用id_rsa文件登录会与authorized_keys中的文件进行验证。 cat id_rsa.pub >> authorized_keys 关闭ssh密码登录 在 /etc/ssh 下的sshd_conf…

Spark集群完全分布式安装部署

Spark集群完全分布式安装部署下载安装配置Spark 1spark-envsh配置2slaves配置3profile配置复制到其他节点测试总结 Spark集群完全分布式安装部署 本文中所提到的Spark集群所用的系统环境是Centos6.5&#xff0c;共4个节点&#xff0c;前提是Hadoop、JDK都已经安装配置好了&…

抛出错误_不用try catch,如何机智的捕获错误

这是多个feature组合使用后实现的神奇效果&#xff0c;在React源码中被广泛使用。当我读源码看到这里时&#xff0c;心情经历了&#xff1a;懵逼 -- 困惑 -- 沉思 -- 查文档 -- 豁然开朗看完此文&#xff0c;相信你也会发出感叹&#xff1a;还能这么玩&#xff1f;起源我们知道…