用Java实现HTTP断点续传功能(副附详细的源代码).doc

上传人:cn****1 文档编号:543881261 上传时间:2022-08-17 格式:DOC 页数:14 大小:58.01KB
返回 下载 相关 举报
用Java实现HTTP断点续传功能(副附详细的源代码).doc_第1页
第1页 / 共14页
用Java实现HTTP断点续传功能(副附详细的源代码).doc_第2页
第2页 / 共14页
用Java实现HTTP断点续传功能(副附详细的源代码).doc_第3页
第3页 / 共14页
用Java实现HTTP断点续传功能(副附详细的源代码).doc_第4页
第4页 / 共14页
用Java实现HTTP断点续传功能(副附详细的源代码).doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《用Java实现HTTP断点续传功能(副附详细的源代码).doc》由会员分享,可在线阅读,更多相关《用Java实现HTTP断点续传功能(副附详细的源代码).doc(14页珍藏版)》请在金锄头文库上搜索。

1、本资料由-大学生创业|创业|创业网http:/ 星期一 16:13(一)断点续传的原理其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:假设服务器域名为,文件名为down.zip。GET /down.zip HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*Accept

2、-Language: zh-cnAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)Connection: Keep-Alive服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下200Content-Length=106786028Accept-Ranges=bytesDate=Mon, 30 Apr 2001 12:56:11 GMTETag=W/02ca57e173c11:95bContent-Type=applicati

3、on/octet-streamServer=Microsoft-IIS/5.0Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给Web服务器的时候要多加一条信息-从哪里开始(客户端提供一个文件偏移)。下面是用自己编的一个浏览器来传递请求信息给Web服务器,要求从2000070字节开始。GET /down.zip HTTP/1.0User-Agent: NetFoxRANGE: bytes=2000070-Accept: text/html, image/gif, image/jpe

4、g, *; q=.2, */*; q=.2仔细看一下就会发现多了一行RANGE: bytes=2000070-这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。服务器收到这个请求以后,返回的信息如下:206Content-Length=106786028Content-Range=bytes 2000070-106786027/106786028Date=Mon, 30 Apr 2001 12:55:20 GMTETag=W/02ca57e173c11:95bContent-Type=application/octet-streamServer=

5、Microsoft-IIS/5.0Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT和前面服务器返回的信息比较一下,就会发现增加了一行:Content-Range=bytes 2000070-106786027/106786028返回的代码也改为206了,而不再是200了。206 Partial Content服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If

6、-Range 来作为请求条件。响应必须包含如下的头部域:Content-Range 用以指示本次响应中返回的内容的范围;如果是 Content-Type 为 multipart/byteranges 的多段下载,则每一 multipart 段中都应包含 Content-Range 域用以指示本段的内容范围。假如响应中包含 Content-Length,那么它的数值必须匹配它返回的内容范围的真实字节数。DateETag 和/或 Content-Location,假如同样的请求本应该返回200响应。Expires, Cache-Control,和/或 Vary,假如其值可能与之前相同变量的其他响应

7、对应的值不同的话。假如本响应请求使用了 If-Range 强缓存验证,那么本次响应不应该包含其他实体头;假如本响应的请求使用了 If-Range 弱缓存验证,那么本次响应禁止包含其他实体头;这避免了缓存的实体内容和更新了的实体头信息之间的不一致。否则,本响应就应当包含所有本应该返回200响 应中应当返回的所有实体头部域。假如 ETag 或 Last-Modified 头部不能精确匹配的话,则客户端缓存应禁止将206响应返回的内容与之前任何缓存过的内容组合在一起。任何不支持 Range 以及 Content-Range 头的缓存都禁止缓存206响应返回的内容。知道了以上原理,就可以进行断点续传的

8、编程了。(二)Java实现断点续传的关键几点 (1)用什么方法实现提交RANGE: bytes=2000070-。当然用最原始的Socket是肯定能完成的,不过那样太费事了,其实Java的net包中提供了这种功能。代码如下:URL url = new URL(http:/ httpConnection = (HttpURLConnection)url.openConnection();/设置User-AgenthttpConnection.setRequestProperty(User-Agent,NetFox);/设置断点续传的开始位置httpConnection.setRequestPro

9、perty(RANGE,bytes=2000070);/获得输入流InputStream input = httpConnection.getInputStream();从输入流中取出的字节流就是down.zip文件从2000070开始的字节流。大家看,其实断点续传用Java实现起来还是很简单的吧。接下来要做的事就是怎么保存获得的流到文件中去了。保存文件采用的方法。我采用的是IO包中的RandAccessFile类。操作相当简单,假设从2000070处开始保存文件,代码如下:RandomAccess oSavedFile = new RandomAccessFile(down.zip,rw);

10、long nPos = 2000070;/定位文件指针到nPos位置oSavedFile.seek(nPos);byte b = new byte1024;int nRead;/从输入流中读入字节流,然后写到文件中while(nRead=input.read(b,0,1024) 0)oSavedFile.write(b,0,nRead);怎么样,也很简单吧。接下来要做的就是整合成一个完整的程序了。包括一系列的线程控制等等。(三)断点续传内核的实现主要用了6个类,包括一个测试类。SiteFileFetch.java负责整个文件的抓取,控制内部线程(FileSplitterFetch类)。File

11、SplitterFetch.java负责部分文件的抓取。FileAccess.java负责文件的存储。SiteInfoBean.java要抓取的文件的信息,如文件保存的目录,名字,抓取文件的URL等。Utility.java工具类,放一些简单的方法。TestMethod.java测试类。下面是源程序: /*SiteFileFetch.java*/package NetFox;import java.io.*;import .*;public class SiteFileFetch extends Thread SiteInfoBean siteInfoBean = null; /文件信息Bea

12、nlong nStartPos; /开始位置long nEndPos; /结束位置FileSplitterFetch fileSplitterFetch; /子线程对象long nFileLength; /文件长度boolean bFirst = true; /是否第一次取文件boolean bStop = false; /停止标志File tmpFile; /文件下载的临时信息DataOutputStream output; /输出到文件的输出流public SiteFileFetch(SiteInfoBean bean) throws IOExceptionsiteInfoBean = b

13、ean;/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();elsenStartPos = new longbean.getNSplitter();nEndPos = new longbean.getNSplitter();public void

14、run()/获得文件长度/分割文件/实例FileSplitterFetch/启动FileSplitterFetch线程/等待子线程返回tryif(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!);elsefor(int i=0;i<nStartPos.length;i+)nStartPosi = (long)(i*(nFileLength/nStartPos.length);for(int i=0;i<nEndPos.length-1;i+)nEndPosi = nStartPosi+1;nEndPosnEndPos.length-1 =

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号