用Java实现断点续传-Java基础-Java-编程开发

Java FTP客户端设计与实现:从基础到高级特性 Java提供了丰富的网络API,包括和类,用于实现基于TCP的网络通信。Socket类代表了一个客户端的连接,它允许我们发送和接收数据;类则用于在服务器端监听特定端口的连接请求。对于FTP客户端来说,其核心任务是通过Socket连接到FTP服务器,并发送相应的FTP命令来实现文件的上传与下载。Java网络API的应用使得这一过程变得简洁和高效。开发者不需要关心底层网络协议的细节,而是通过高层次的API来实现复杂的网络操作。// 示例代码:简单的TCP客户端Socket连接。 阅读详情
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

(一)断点续传的原理
其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。
打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:
假设服务器域名为wwww.sjtu.edu.cn,文件名为down.zip。

GET /down.zip HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
excel, application/msword, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Connection: Keep-Alive

服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:
200
Content-Length=106786028
Accept-Ranges=bytes
Date=Mon, 30 Apr 2001 12:56:11 GMT
ETag=W/"02ca57e173c11:95b"
Content-Type=application/octet-stream
Server=Microsoft-IIS/5.0
Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT

所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给
Web服务器的时候要多加一条信息--从哪里开始。
下面是用自己编的一个"浏览器"来传递请求信息给Web服务器,要求从2000070字节开始。
GET /down.zip HTTP/1.0
User-Agent: NetFox
RANGE: bytes=2000070-
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2


仔细看一下就会发现多了一行RANGE: bytes=2000070-
这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。
服务器收到这个请求以后,返回的信息如下:
206
Content-Length=106786028
Content-Range=bytes 2000070-106786027/106786028
Date=Mon, 30 Apr 2001 12:55:20 GMT
ETag=W/"02ca57e173c11:95b"
Content-Type=application/octet-stream
Server=Microsoft-IIS/5.0
Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT

和前面服务器返回的信息比较一下,就会发现增加了一行:
Content-Range=bytes 2000070-106786027/106786028
返回的代码也改为206了,而不再是200了。

知道了以上原理,就可以进行断点续传的编程了。

(二)Java实现断点续传的关键几点

(1)用什么方法实现提交RANGE: bytes=2000070-。
当然用最原始的Socket是肯定能完成的,不过那样太费事了,其实Java的net包中提供了这种功能。代码如下:
URL url = new URL("http://www.sjtu.edu.cn/down.zip");
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection

();
//设置User-Agent
httpConnection.setRequestProperty("User-Agent","NetFox");
//设置断点续传的开始位置
httpConnection.setRequestProperty("RANGE","bytes=2000070");
//获得输入流
InputStream input = httpConnection.getInputStream();

从输入流中取出的字节流就是down.zip文件从2000070开始的字节流。
大家看,其实断点续传用Java实现起来还是很简单的吧。
接下来要做的事就是怎么保存获得的流到文件中去了。

保存文件采用的方法
我采用的是IO包中的RandAccessFile类。
操作相当简单,假设从2000070处开始保存文件,代码如下:
RandomAccess oSavedFile = new RandomAccessFile("down.zip","rw");
long nPos = 2000070;
//定位文件指针到nPos位置
oSavedFile.seek(nPos);
byte[] b = new byte[1024];
int nRead;
//从输入流中读入字节流,然后写到文件中
while((nRead=input.read(b,0,1024)) >0)
{
oSavedFile.write(b,0,nRead);
}

怎么样,也很简单吧。
接下来要做的就是整合成一个完整的程序了。包括一系列的线程控制等等。

(三)断点续传内核的实现
主要用了6个类,包括一个测试类。
SiteFileFetch.java负责整个文件的抓取,控制内部线程(FileSplitterFetch类)。
FileSplitterFetch.java负责部分文件的抓取。
FileAccess.java负责文件的存储。
SiteInfoBean.java要抓取的文件的信息,如文件保存的目录,名字,抓取文件的URL等。
Utility.java工具类,放一些简单的方法。
TestMethod.java测试类。

下面是源程序:
/*
**SiteFileFetch.java
*/
package NetFox;
import java.io.*;
import java.net.*;

public class SiteFileFetch extends Thread {

SiteInfoBean siteInfoBean = null; //文件信息Bean
long[] nStartPos; //开始位置
long[] nEndPos; //结束位置
FileSplitterFetch[] fileSplitterFetch; //子线程对象
long nFileLength; //文件长度
boolean bFirst = true; //是否第一次取文件
boolean bStop = false; //停止标志
File tmpFile; //文件下载的临时信息
DataOutputStream output; //输出到文件的输出流

public SiteFileFetch(SiteInfoBean bean) throws IOException
{
siteInfoBean = bean;
//tmpFile = File.createTempFile ("zhong","1111",new File(bean.getSFilePath()));
tmpFile = new File(bean.getSFilePath() File.separator bean.getSFileName() ".info");
if(tmpFile.exists ())
{
bFirst = false;
read_nPos();
}
else
{
nStartPos = new long[bean.getNSplitter()];
nEndPos = new long[bean.getNSplitter()];
}

}

public void run()
{
//获得文件长度
//分割文件
//实例FileSplitterFetch
//启动FileSplitterFetch线程
//等待子线程返回
try{
if(bFirst)
{
nFileLength = getFileSize();
if(nFileLength == -1)
{
System.err.println("File Length is not known!");
}
else if(nFileLength == -2)
{
System.err.println("File is not access!");
}
else
{
for(int i=0;i {
nStartPos[i] = (long)(i*(nFileLength/nStartPos.length));
}
for(int i=0;i {
nEndPos[i] = nStartPos[i 1];
}
nEndPos[nEndPos.length-1] = nFileLength;
}
}

//启动子线程
fileSplitterFetch = new FileSplitterFetch[nStartPos.length];
for(int i=0;i {
fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean.getSSiteURL(),
siteInfoBean.getSFilePath() File.separator siteInfoBean.getSFileName(),
nStartPos[i],nEndPos[i],i);
Utility.log("Thread " i " , nStartPos = " nStartPos[i] ", nEndPos = " nEndPos[i]);
fileSplitterFetch[i].start();
}
// fileSplitterFetch[nPos.length-1] = new FileSplitterFetch(siteInfoBean.getSSiteURL(),
siteInfoBean.getSFilePath() File.separator siteInfoBean.getSFileName(),nPos[nPos.length-1],nFileLength,nPos.length-1);
// Utility.log("Thread " (nPos.length-1) " , nStartPos = " nPos[nPos.length-1] ",
nEndPos = " nFileLength);
// fileSplitterFetch[nPos.length-1].start();

//等待子线程结束
//int count = 0;
//是否结束while循环
boolean breakWhile = false;

while(!bStop)
{
write_nPos();
Utility.sleep(500);
breakWhile = true;

for(int i=0;i {
if(!fileSplitterFetch[i].bDownOver)
{
breakWhile = false;
break;
}
}
if(breakWhile)
break;

//count ;
//if(count>4)
// siteStop();
}

System.err.println("文件下载结束!");
}
catch(Exception e){e.printStackTrace ();}
}

//获得文件长度
public long getFileSize()
{
int nFileLength = -1;
try{
URL url = new URL(siteInfoBean.getSSiteURL());
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection ();
httpConnection.setRequestProperty("User-Agent","NetFox");

int responseCode=httpConnection.getResponseCode();
if(responseCode>=400)
{
processErrorCode(responseCode);
return -2; //-2 represent access is error
}

String sHeader;

for(int i=1;;i )
{
//DataInputStream in = new DataInputStream(httpConnection.getInputStream ());
//Utility.log(in.readLine());
sHeader=httpConnection.getHeaderFieldKey(i);
if(sHeader!=null)
{
if(sHeader.equals("Content-Length"))
{
nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader));
break;
}
}
else
break;
}
}
catch(IOException e){e.printStackTrace ();}
catch(Exception e){e.printStackTrace ();}

Utility.log(nFileLength);

return nFileLength;
}

//保存下载信息(文件指针位置)
private void write_nPos()
{
try{
output = new DataOutputStream(new FileOutputStream(tmpFile));
output.writeInt(nStartPos.length);
for(int i=0;i {
// output.writeLong(nPos[i]);
output.writeLong(fileSplitterFetch[i].nStartPos);
output.writeLong(fileSplitterFetch[i].nEndPos);
}
output.close();
}
catch(IOException e){e.printStackTrace ();}
catch(Exception e){e.printStackTrace ();}
}

[1] [2]

Java实现FTP断点续传的详细指南 断点续传是一种数据传输技术,当文件传输被中断时,能够从中断的位置继续传输,而不是重新开始。这种技术减少了因网络问题导致的重复数据传输,显著提高了大文件传输的成功率和效率。FTPClient类提供了许多与FTP服务器进行交互的方法。这里介绍几个基本的常用方法:: 连接到FTP服务器。: 使用用户名和密码登录到FTP服务器。logout(): 断开与FTP服务器的连接并注销登录。: 设置文件传输类型,常用的是和。以下是这些方法的基本使用:// 连接到FTP服务器。 阅读详情

相关推荐

Java多线程与线程安全实现断点续传实战指南

本文还有配套的精品资源,点击获取 简介:本文深入探讨Java多线程编程和线程安全问题,并展示如何将这些概念应用于基于HTTP协议的断点续传功能。我们将了解多线程的基本概念、Java提供的多线程模型和工具、以及线程安全的多种机制。此外,文章还将涵盖实现断点续传时的关键知识点,包括HTTP协议的使用、HTTP头信息处理、文件分块、多线程下载、状态保存、异常处理以及协调与同步。所...

weixin_34618526的博客 937

【开发经验】java 20行代码实现断点续传

随着文件的越来越大,很多场景需要断点续传功能,这个功能很友好,大文件上传了一半,下次还能接着上传,免得断点或者关机之后还需要从头开始。 断点上传思路很简单,只需要在上传时将大文件切割为多个分片,将这些小的分片进行上传。

叁滴水 的博客 1万+

Java编程实现文件断点续传技术详解

HTTP请求头的定义和设置在多数现代Web开发框架中都得到了很好的支持。以Java中的HttpClient为例,可以通过以下方式定义和设置请求头:.build();在这个例子中,我们创建了一个带有两个请求头字段(”User-Agent”和”Accept”)的HTTP GET请求。这些字段向服务器提供了有关客户端请求的信息。Spring MVC是Spring框架的一个模块,它提供了一种基于Java的、可扩展的MVC(Model-View-Controller)实现,用于构建Web应用程序。

weixin_42627459的博客 557

JAVA 实现 HTTP 断点续传及原理

断点续传原理: 现在有一个文件需要我们进行下载,当我们下载了一部分的时候,出现情况了,比如:电脑死机、没电、网络中断等等。 对于以上行为,如果“下载”的行为无法记录本次下载的一个进度。那么,当我们再次下载这个文件也就只能从头来过。 所以,要实现让一种断开的行为“续”起来的目的,关键就在于要有“介质”能够记录和读取行为出现”中断”的这个节点的信息。 实际上这就是“断点续传”的基础原理,用大白话

二一点 7265

Java文件上传下载及断点续传实现指南

Java NIO(New Input/Output)是一种基于通道(Channel)和缓冲区(Buffer)的I/O操作方法,它提供了与传统Java IO相同的API,但性能更优。Java NIO支持面向缓冲的(Buffer-oriented)、基于通道的(Channel-based)I/O操作。NIO使开发者能够管理多个并发连接,并提供了更好的I/O性能。与Java IO不同,NIO是基于事件的。

weixin_42443533的博客 904

Java实现FTP断点续传的实践指南

FTP协议是一种基于客户端-服务器模式的协议,它允许用户从一台计算机(服务器)向另一台计算机(客户端)传输文件。与其它协议相比,FTP具有独特的优点:如支持断点续传、支持匿名访问等。为了在项目中使用Apache Commons Net库,首先需要将其添加到项目依赖中。如果是通过Maven管理依赖,则在pom.xml文件中添加如下配置:--请检查最新版本号-->非Maven项目则需要下载jar包,并将其添加到项目的类路径中。

weixin_32445049的博客 794

Java断点续传实现原理很简单

原理解析在开发当中,“断点续传”这种功能很实用和常见,听上去也是比较有“逼格”的感觉。所以通常我们都有兴趣去研究研究这种功能是如何实现的? 以Java来说,网络上也能找到不少关于实现类似功能的资料。但是呢,大多数都是举个Demo然后贴出源码,真正对其实现原理有详细的说明很少。 于是我们在最初接触的时候,很可能就是直接Crtl + C/V代码,然后捣鼓捣鼓,然而最终也能把效果弄出来。但初学时这

LaterEqualsNever 2万+

飞书+扣子+DeepSeek三件套:5分钟搞定公众号文章批量改写(附完整配置截图)

本文详细介绍了如何利用飞书、扣子和DeepSeek三款工具,无需编程即可搭建一个高效的公众号文章批量改写自动化工作流。通过飞书多维表格管理链接与成果,扣子平台串联整个流程,并调用DeepSeek智能体进行内容润色与改写,实现从内容抓取到智能处理的完整自动化,大幅提升新媒体运营效率。

python9snake的博客 211

java 实现断点续传服务

java 实现断点续传服务 一:什么是断点续传 客户端软件断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载 (将文件分片以及后续合并是一个不小的工作量,由于项目时间有限,我并没有做分片,只是实现了可断点下载) 二:实现原理 2.1 实现思路 需要前端和后端的配合,前端在请求头中 标明 下载开始的位置,后端重标记位置开始向前端输出

qq_50990903的博客 8602

粒子群算法Particle Swarm Optimization超详细解析+代码实例讲解

粒子群算法,也称粒子群优化算法或鸟群觅食算法(Particle Swarm Optimization),缩写为 PSO, 是近年来由J. Kennedy和R. C. Eberhart等开发的一种新的进化算法(Evolutionary Algorithm - EA)。

猫敷雪 894

SAP 管道业务(Pipeline Procurement)是用于水、电、气等不间断供应且无库存管理的物料采购场景,核心是消耗即记账、无库存持有,通过 MM-FI 集成实现实时负债与成本过账

摘要:SAP管道业务适用于水电气等无库存管理的物料采购场景,通过消耗即记账机制实现实时负债与成本过账。核心配置包括创建PIPE物料类型(无库存管理)、维护管道采购信息记录、配置自动记账科目等。SAP PO可集成外部系统实现流程自动化,如自动过账提取数据、发票校验等。实施要点在于物料主数据、信息记录和科目确定的精准配置,以及PO接口的可靠对接,最终构建端到端的高效采购与财务结算体系。

金牌架构师 749

java断点续传原理_很简单的Java断点续传实现原理

原理解析在开发当中,“断点续传”这种功能很实用和常见,听上去也是比较有“逼格”的感觉。所以通常我们都有兴趣去研究研究这种功能是如何实现的?以Java来说,网络上也能找到不少关于实现类似功能的资料。但是呢,大多数都是举个Demo然后贴出源码,真正对其实现原理有详细的说明很少。于是我们在最初接触的时候,很可能就是直接Crtl + C/V代码,然后捣鼓捣鼓,然而最终也能把效果弄出来。但初学时这样做其实很...

weixin_31938727的博客 2123

uni-app - 手机端实现用户长按文本提示选取复制功能

手机端实现用户长按文本提示选取复制功能 需求:用户手指长按文本区域,弹出手机系统复制功能。 有时,安卓或苹果用户会有复制文本的需求,但是uni-app编译后组件是无法长按选取复制的。 实现 最简单的方式,就是将<text>标签selectable属性设置为true,演示如下: <textselectable="true">这是一个可以长按选择文本,弹出复制的text标签</tex...

🏆 前端领域优质创作者 1万+

Java断点续传

以下内容转载自作者LaterEqualsNever 原文链接:https://blog.youkuaiyun.com/ghost_Programmer/article/details/51923895 原理解析 在开发当中,“断点续传”这种功能很实用和常见,听上去也是比较有“逼格”的感觉。所以通常我们都有兴趣去研究研究这种功能是如何实现的? 以Java来说,网络上也能找到不少关...

likecandy的博客 3403

11.8 LangGraph生产级AI Agent开发:从节点定义到高并发架构的终极指南

本文介绍了如何使用 LangGraph 构建生产级 AI Agent,重点解析了 LangGraph 的核心设计、节点与边的实现方法论、生产级实现技巧以及性能优化策略。LangGraph 通过图结构抽象复杂 AI 工作流,核心组件包括节点、边、状态和检查点。节点通过 Python 函数封装原子业务逻辑,边通过条件分支实现动态工作流。生产级实现技巧包括状态管理、多会话控制和错误处理机制。性能优化策略涉及并行执行和缓存机制设计。文章还提供了旅行规划 Agent 的实战案例和常见问题解决方案,帮助开发者构建高效、

yonggeit的博客 3272

南 京 农 业 大 学 试 题 纸 附表(rape.csv)是25个油菜材料,测得每个材料的千粒重、亚油酸等的含量. (1) 对物质含量的八个指标作主成分分析,画出碎石图和主成分得分图; (2) 选

(1)请用n1

Mrrunsen的博客 498

JAVA编程技巧之如何实现HTTP的断点续传(原理篇)

JAVA编程技巧之如何实现HTTP的断点续传(原理篇)

fdyufgf的博客 952

Win7 x64位系统下几乎完美使用安装RTX3050 6G显卡驱动详细教程

RTX3050 6G显卡驱动安装指南:由于该显卡发布时间晚于驱动,需手动修改安装文件。首先在NVIDIA官网下载驱动并解压,通过设备管理器获取硬件ID(PCI\VEN_10DE&DEV_2584),然后在解压目录的.inf文件中添加对应的设备标识。安装完成后可能出现设备管理器感叹号问题,推荐通过命令提示符启用测试模式(bcdedit /set testsigning on)解决,此方法无需每次启动按F8,但会显示测试模式水印。文中提供了详细的图文操作步骤和两种解决方案。

m0_67194883的博客 2897

用Java实现断点续传

服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:200Content-Length=106786028Accept-Ranges=bytesDate=Mon, 30 Apr 2001 12:56:11 GMTETag=W/"02ca57e173c11:95b"Content-Type=application/octet-streamServer=Micros

Stone的专栏 1849

【YOLO部署Android安卓手机APP】YOLO11部署到安卓实时目标检测识别——以火焰烟雾目标检测识别举例(可自定义更换其他目标)

本项目基于YOLOv11部署到手机APP实现对火焰烟雾的检测识别,当然,以此你可以按照本项目开发步骤扩展更换为其他目标进行检测,例如更换为车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物等等部署手机APP进行检测。本文为详细设计/配置文档,包含完整所需的环境配置搭建,项目工程配置步骤等,手把手记录使用pycharm和Android studio的工程开发过程,实现YOLO部署到安卓。实战开发,亲测无误。演示视频训练了50轮进行了展示(为演示,训练轮数较少,你可以训练轮数多些

嵌入式阿齐Archie 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

用 Java 实现断点续传 (HTTP)

断点续传的原理 其实断点续传的原理很简单,就是在 Http 的请求上和一般的下载有所不同而已。 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下: 假设服务器域名为 wwww.sjtu.edu.cn,文件名为 down.zip。 GET /down.zip HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image...

cowboy258的博客 1812

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【Java 基础篇】Java网络编程:实现文件断点续传功能

断点续传是一种文件下载技术,允许用户在下载文件时,如果下载中断或失败,可以从上次中断的地方继续下载,而无需重新开始下载整个文件。这提高了下载效率,节省了时间和带宽。实现断点续传的核心思想是将文件分成多个块,然后在下载时只请求未下载的块,最后将这些块合并成完整的文件。文件断点续传是一个有用的功能,可以提高文件下载的效率并节省时间。通过合理设置Range头部请求,您可以轻松实现断点续传功能。在实际应用中,可以将这些代码封装成一个可重用的工具类,以便在多个项目中使用。

繁依Fanyi的博客 1013

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

断点续传JAVA实现

断点续传JAVA实现 支持H5 Video标签播放,迅雷下载 /** * 断点续传工具 * @author lxycx_xc * 时间:2017年11月30日 */ public class BreakpointResume { private static Logger log = Logger.getLogger(...

w1366352655的博客 1040

JAVA编程技巧之如何实现HTTP的断点续传

cx510158746的专栏 597
上一篇: 用Java生成gif动画-Java基础-Java-编程开发
下一篇: 对象引用是怎样严重影响垃圾收集器的-Java基础-Java-编程开发
java169
博客等级 码龄19年 27粉丝 2568原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值