




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、用Java实现HTTP断点续传功能.2007年06月25日星期一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, */*Acc
2、ept-Language: zh-cnAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0Connection: Keep-Alive服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下200Content-Length=106786028Accept-Ranges=bytesDate=Mon, 30 Apr 2001 12:56:11 GMTETag=W/"02ca57e173c11:95b"Content-
3、Type=application/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/g
4、if, image/jpeg, *; 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:95b"Content-Type=applic
5、ation/octet-streamServer=Microsoft-IIS/5.0Last-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包中提供了这种功
6、能。代码如下:URL url = new URL("HttpURLConnection httpConnection = (HttpURLConnectionurl.openConnection(;/设置User-AgenthttpConnection.setRequestProperty("User-Agent","NetFox"/设置断点续传的开始位置httpConnection.setRequestProperty("RANGE","bytes=2000070"/获得输入流InputStream i
7、nput = httpConnection.getInputStream(;从输入流中取出的字节流就是down.zip文件从2000070开始的字节流。大家看,其实断点续传用Java实现起来还是很简单的吧。接下来要做的事就是怎么保存获得的流到文件中去了。保存文件采用的方法。我采用的是IO包中的RandAccessFile类。操作相当简单,假设从2000070处开始保存文件,代码如下:RandomAccess oSavedFile = new RandomAccessFile("down.zip","rw"long nPos = 2000070;/定位文件
8、指针到nPos位置oSavedFile.seek(nPos;byte b = new byte1024;int nRead;/从输入流中读入字节流,然后写到文件中while(nRead=input.read(b,0,1024 > 0oSavedFile.write(b,0,nRead;怎么样,也很简单吧。接下来要做的就是整合成一个完整的程序了。包括一系列的线程控制等等。(三断点续传内核的实现主要用了6个类,包括一个测试类。SiteFileFetch.java负责整个文件的抓取,控制内部线程(FileSplitterFetch类。FileSplitterFetch.java负责部分文件的抓
9、取。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; /文件信息Beanlong nStartPos; /开始位置long
10、nEndPos; /结束位置FileSplitterFetch fileSplitterFetch; /子线程对象long nFileLength; /文件长度boolean bFirst = true; /是否第一次取文件boolean bStop = false; /停止标志File tmpFile; /文件下载的临时信息DataOutputStream output; /输出到文件的输出流public SiteFileFetch(SiteInfoBean bean throws IOExceptionsiteInfoBean = bean;/tmpFile = File.createTe
11、mpFile ("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
12、 run(/获得文件长度/分割文件/实例FileSplitterFetch/启动FileSplitterFetch线程/等待子线程返回tryif(bFirstnFileLength = getFileSize(;if(nFileLength = -1System.err.println("File Length is not known!"else if(nFileLength = -2System.err.println("File is not access!"elsefor(int i=0;i<nStartPos.length;i+nStar
13、tPosi = (long(i*(nFileLength/nStartPos.length;for(int i=0;i<nEndPos.length-1;i+nEndPosi = nStartPosi+1;nEndPosnEndPos.length-1 = nFileLength;/启动子线程fileSplitterFetch = new FileSplitterFetchnStartPos.length;for(int i=0;i<nStartPos.length;i+fileSplitterFetchi = new FileSplitterFetch(siteInfoBean.
14、getSSiteURL(,siteInfoBean.getSFilePath( + File.separator + siteInfoBean.getSFileName(,nStartPosi,nEndPosi,i;Utility.log("Thread " + i + " , nStartPos = " + nStartPosi + ", nEndPos = " + nEndPosi; fileSplitterFetchi.start(;/ fileSplitterFetchnPos.length-1 = new FileSplit
15、terFetch(siteInfoBean.getSSiteURL(, siteInfoBean.getSFilePath( + File.separator + siteInfoBean.getSFileName(,nPosnPos.length-1,nFileLength,nPos.length-1;/ Utility.log("Thread " + (nPos.length-1 + " , nStartPos = " + nPosnPos.length-1 + ", nEndPos = " + nFileLength;/ fil
16、eSplitterFetchnPos.length-1.start(;/等待子线程结束/int count = 0;/是否结束while循环boolean breakWhile = false;while(!bStopwrite_nPos(;Utility.sleep(500;breakWhile = true;for(int i=0;i<nStartPos.length;i+if(!fileSplitterFetchi.bDownOverbreakWhile = false;break;if(breakWhilebreak;/count+;/if(count>4/ siteSto
17、p(;System.err.println("文件下载结束!"catch(Exception ee.printStackTrace (;/获得文件长度public long getFileSize(int nFileLength = -1;tryURL url = new URL(siteInfoBean.getSSiteURL(;HttpURLConnection httpConnection = (HttpURLConnectionurl.openConnection (; httpConnection.setRequestProperty("User-Age
18、nt","NetFox"int responseCode=httpConnection.getResponseCode(;if(responseCode>=400processErrorCode(responseCode;return -2; /-2 represent access is errorString sHeader;for(int i=1;i+/DataInputStream in = new DataInputStream(httpConnection.getInputStream (;/Utility.log(in.readLine(;sH
19、eader=httpConnection.getHeaderFieldKey(i;if(sHeader!=nullif(sHeader.equals("Content-Length"nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader;break;elsebreak;catch(IOException ee.printStackTrace (;catch(Exception ee.printStackTrace (;Utility.log(nFileLength;return nFileLe
20、ngth;/保存下载信息(文件指针位置private void write_nPos(tryoutput = new DataOutputStream(new FileOutputStream(tmpFile;output.writeInt(nStartPos.length;for(int i=0;i<nStartPos.length;i+/ output.writeLong(nPosi;output.writeLong(fileSplitterFetchi.nStartPos;output.writeLong(fileSplitterFetchi.nEndPos;output.clos
21、e(;catch(IOException ee.printStackTrace (;catch(Exception ee.printStackTrace (;/读取保存的下载信息(文件指针位置private void read_nPos(tryDataInputStream input = new DataInputStream(new FileInputStream(tmpFile; int nCount = input.readInt(;nStartPos = new longnCount;nEndPos = new longnCount;for(int i=0;i<nStartPo
22、s.length;i+nStartPosi = input.readLong(;nEndPosi = input.readLong(;input.close(;catch(IOException ee.printStackTrace (;catch(Exception ee.printStackTrace (;private void processErrorCode(int nErrorCodeSystem.err.println("Error Code : " + nErrorCode;/停止文件下载public void siteStop(bStop = true;f
23、or(int i=0;i<nStartPos.length;i+fileSplitterFetchi.splitterStop(;/*FileSplitterFetch.java*/package NetFox;import java.io.*;import .*;public class FileSplitterFetch extends Thread String sURL; /File URLlong nStartPos; /File Snippet Start Positionlong nEndPos; /File Snippet End Positionint nThreadI
24、D; /Thread's IDboolean bDownOver = false; /Downing is overboolean bStop = false; /Stop identicalFileAccessI fileAccessI = null; /File Access interfacepublic FileSplitterFetch(String sURL,String sName,long nStart,long nEnd,int id throws IOExceptionthis.sURL = sURL;this.nStartPos = nStart;this.nEn
25、dPos = nEnd;nThreadID = id;fileAccessI = new FileAccessI(sName,nStartPos;public void run(while(nStartPos < nEndPos && !bStoptryURL url = new URL(sURL;HttpURLConnection httpConnection = (HttpURLConnectionurl.openConnection (; httpConnection.setRequestProperty("User-Agent","N
26、etFox"String sProperty = "bytes="+nStartPos+"-"httpConnection.setRequestProperty("RANGE",sProperty;Utility.log(sProperty;InputStream input = httpConnection.getInputStream(;/logResponseHead(httpConnection;byte b = new byte1024;int nRead;while(nRead=input.read(b,0,10
27、24 > 0 && nStartPos < nEndPos && !bStop nStartPos += fileAccessI.write(b,0,nRead;/if(nThreadID = 1/ Utility.log("nStartPos = " + nStartPos + ", nEndPos = " + nEndPos;Utility.log("Thread " + nThreadID + " is over!"bDownOver = true;/nPos =
28、fileAccessI.write (b,0,nRead;catch(Exception ee.printStackTrace (;/打印回应的头信息public void logResponseHead(HttpURLConnection confor(int i=1;i+String header=con.getHeaderFieldKey(i;if(header!=null/responseHeaders.put(header,httpConnection.getHeaderField(header;Utility.log(header+" : "+con.getHe
29、aderField(header;elsebreak;public void splitterStop(bStop = true;/*FileAccess.java*/package NetFox;import java.io.*;public class FileAccessI implements SerializableRandomAccessFile oSavedFile;long nPos;public FileAccessI( throws IOExceptionthis("",0;public FileAccessI(String sName,long nPo
30、s throws IOException oSavedFile = new RandomAccessFile(sName,"rw"this.nPos = nPos;oSavedFile.seek(nPos;public synchronized int write(byte b,int nStart,int nLenint n = -1;tryoSavedFile.write(b,nStart,nLen;n = nLen;catch(IOException ee.printStackTrace (;本资料由-大学生创业|创业|创业网 return n; /* *SiteIn
31、foBean.java */ package NetFox; public class SiteInfoBean private String sSiteURL; /Site's URL private String sFilePath; /Saved File's Path private String sFileName; /Saved File's Name private int nSplitter; /Count of Splited Downloading File public SiteInfoBean( /default value of nSplitt
32、er is 5 this("","","",5; public SiteInfoBean(String sURL,String sPath,String sName,int nSpiltter sSiteURL= sURL; sFilePath = sPath; sFileName = sName; this.nSplitter = nSpiltter; public String getSSiteURL( return sSiteURL; public void setSSiteURL(String value sSiteURL =
33、 value; 在线代理|网页代理|代理网页| 减肥药排行榜|淘宝最好的减肥药|什么减肥药效果最好|减肥瘦身药| 本资料由-大学生创业|创业|创业网 public String getSFilePath( return sFilePath; public void setSFilePath(String value sFilePath = value; public String getSFileName( return sFileName; public void setSFileName(String value sFileName = value; public int getNSplitte
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版文化产业园项目策划与运营合同范本
- 2025版办公楼半包装修设计与施工合同样本
- 2025版古建筑修复劳务合同规范文本
- 2025版某局数据中心建设项目劳务分包结算执行合同
- 2025版智能仓储厂房租赁及自动化设备集成合同
- 二零二五年度电商企业数字化转型服务合同
- 二零二五年度住宅租赁代理服务全面合作协议
- 2025版加油站加油站设施设备更新改造合同
- 2025年浙江省事业单位招聘考试教师招聘语文教学评价标准学科专业知识试卷
- 二零二五年度房地产股权置换与转让合同规范
- 甲状腺相关性眼病的诊治
- 用人单位职业卫生档案(加油站)
- GB/T 35786-2017机动车电子标识读写设备通用规范
- GB/T 19378-2003农药剂型名称及代码
- 《经济学基础》教案
- DB37T242-2021建筑消防设施检测技术规程
- 供应商库入库资料
- 桥台裂缝加固处理方案
- 脚手架架在楼板上验算书
- ThinkPad X220 拆机解析深入分析
- Toolbox中文使用说明(图例)
评论
0/150
提交评论