断点续传的Java桌面程序

本文介绍了断点续传的概念,解释了其实现方式,即在下载时保存文件节点信息,以便在网络故障后从已下载部分继续。通过分析info文件,向服务器请求从特定位置继续传输。文章还提供了涉及6个类的Java代码实现,包括SiteFileFetch、FileSplitterFetch等,实现了断点续传功能,并展示了测试运行结果。部分下载的视频可以播放已下载的内容。
摘要由CSDN通过智能技术生成

说明

断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度。常见的支持断点续传的上传、下载软件:QQ旋风、迅雷、快车(迷你快车)、web迅雷、影音传送带、快车、BitComet、电驴eMule、哇嘎Vagaa、RF[RaySourse/RayFile]、酷6、土豆、优酷、百度视频、新浪视频、腾讯视频、百度云等都支持断点续传。

实现方式

在下载文件的同时,创建一个info文件保存传输的文件节点,当服务器断开或者暂停下载的时候,通过info文件记录已下载的结点位置,当再次进行下载任务的时候,将info文件进行分析,告诉服务器需要继续传输的文件节点位置进行续传操作。例如如下面要求从 1526118 字节开始:

GET http://ozcte1ybf.bkt.clouddn.com/level5.mp4 HTTP/1.0
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
RANGE: bytes=1526118-
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
这里多了一行 RANGE: bytes=1526118- 

这一行的意思就是告诉服务器level5.mp4这个文件从 1526118 字节开始传,前面的字节不用传了。 服务器收到这个请求以后,返回的信息如下: 

206
Content-Length=15261183
Content-Range=bytes 1526118-15261182/15261183
Date=Wed, 27 Dec 2017 09:17:07 GMT
ETag="A1A1A8B84E5C2F5E7A16E0886721419E"
Content-Type=application/octet-stream
Server=Tengine
Last-Modified=Sun, 22 Jan 2017 15:13:55 GMT
返回的信息增加了一行: Content-Range=bytes 1526118-15261182/15261183

返回的代码也变成 206 ,而不再是 200 了。知道了这些原理,就可以进行断点续传的编程了。

注:206状态码含义:
206 Partial Content

服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。
该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。
响应必须包含如下的头部域:
Content-Range 用以指示本次响应中返回的内容的范围;如果是 Content-Type 为 multipart/byteranges 的多段下载,则每一 multipart 段中都应包含 Content-Range 域用以指示本段的内容范围。假如响应中包含 Content-Length,那么它的数值必须匹配它返回的内容范围的真实字节数。
Date
ETag 和/或 Content-Location,假如同样的请求本应该返回200响应。
Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应对应的值不同的话。
假如本响应请求使用了 If-Range 强缓存验证,那么本次响应不应该包含其他实体头;假如本响应的请求使用了 If-Range 弱缓存验证,那么本次响应禁止包含其他实体头;这避免了缓存的实体内容和更新了的实体头信息之间的不一致。否则,本响应就应当包含所有本应该返回200响应中应当返回的所有实体头部域。
假如 ETag 或 Last-Modified 头部不能精确匹配的话,则客户端缓存应禁止将206响应返回的内容与之前任何缓存过的内容组合在一起。

具体代码

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

TestMethod.java          测试类。

FileAccess.java

package fileHandling;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;

/**
 * 
 * 负责文件的存储
 * @author yunlingfly
 * @since 2018-3-11
 * 
 */
public class FileAccess implements Serializable {
	private static final long serialVersionUID = -6335788938054788024L;

	RandomAccessFile oSavedFile;

	long nPos;

	public FileAccess() throws IOException {
		this("", 0);
	}

	public FileAccess(String sName, long nPos) throws IOException {
		oSavedFile = new RandomAccessFile(sName, "rw");
		this.nPos = nPos;
		oSavedFile.seek(nPos);
	}

	public synchronized int write
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值