用Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)_第1頁(yè)
用Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)_第2頁(yè)
用Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)_第3頁(yè)
用Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)_第4頁(yè)
用Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、斷點(diǎn)續(xù)傳的原理其實(shí)斷點(diǎn)續(xù)傳的原理很簡(jiǎn)單,就是在Http的請(qǐng)求上和一般的下載有所不同而已。 打個(gè)比方,瀏覽器請(qǐng)求服務(wù)器上的一個(gè)文時(shí),所發(fā)出的請(qǐng)求如下: 假設(shè)服務(wù)器域名為,文件名為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

2、-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Connection: Keep-Alive服務(wù)器收到請(qǐng)求后,按要求尋找請(qǐng)求的文件,提取文件的信息,然后返回給瀏覽器,返回信息如下:200 Content-Length=106786028 Accept-Ranges=bytes Date=Mon, 30 Apr 2001 12:56:11 GMT ETa

3、g=W/"02ca57e173c11:95b" Content-Type=application/octet-stream Server=Microsoft-IIS/5.0 Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT所謂斷點(diǎn)續(xù)傳,也就是要從文件已經(jīng)下載的地方開(kāi)始繼續(xù)下載。所以在客戶(hù)端瀏覽器傳給 Web服務(wù)器的時(shí)候要多加一條信息-從哪里開(kāi)始。 下面是用自己編的一個(gè)"瀏覽器"來(lái)傳遞請(qǐng)求信息給Web服務(wù)器,要求從2000070字節(jié)開(kāi)始。 GET /down.zip H

4、TTP/1.0 User-Agent: NetFox RANGE: bytes=2000070- Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2仔細(xì)看一下就會(huì)發(fā)現(xiàn)多了一行RANGE: bytes=2000070- 這一行的意思就是告訴服務(wù)器down.zip這個(gè)文件從2000070字節(jié)開(kāi)始傳,前面的字節(jié)不用傳了。 服務(wù)器收到這個(gè)請(qǐng)求以后,返回的信息如下: 206 Content-Length=106786028 Content-Range=by

5、tes 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和前面服務(wù)器返回的信息比較一下,就會(huì)發(fā)現(xiàn)增加了一行: Content-Range=bytes 2000070-10678

6、6027/106786028 返回的代碼也改為206了,而不再是200了。知道了以上原理,就可以進(jìn)行斷點(diǎn)續(xù)傳的編程了。 Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳的關(guān)鍵幾點(diǎn)1. (1)用什么方法實(shí)現(xiàn)提交RANGE: bytes=2000070-。 當(dāng)然用最原始的Socket是肯定能完成的,不過(guò)那樣太費(fèi)事了,其實(shí)Java的net包中提供了這種功能。代碼如下: URL url = new URL("HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection(); /設(shè)置Use

7、r-Agent httpConnection.setRequestProperty("User-Agent","NetFox"); /設(shè)置斷點(diǎn)續(xù)傳的開(kāi)始位置 httpConnection.setRequestProperty("RANGE","bytes=2000070"); /獲得輸入流 InputStream input = httpConnection.getInputStream(); 從輸入流中取出的字節(jié)流就是down.zip文件從2000070

8、開(kāi)始的字節(jié)流。 大家看,其實(shí)斷點(diǎn)續(xù)傳用Java實(shí)現(xiàn)起來(lái)還是很簡(jiǎn)單的吧。 接下來(lái)要做的事就是怎么保存獲得的流到文件中去了。2. 保存文件采用的方法。 我采用的是IO包中的RandAccessFile類(lèi)。 操作相當(dāng)簡(jiǎn)單,假設(shè)從2000070處開(kāi)始保存文件,代碼如下: RandomAccess oSavedFile = new RandomAccessFile("down.zip","rw"); long nPos = 2000070; /定位文件指針到nPos位置 oSavedFile.seek(n

9、Pos); byte b = new byte1024; int nRead; /從輸入流中讀入字節(jié)流,然后寫(xiě)到文件中 while(nRead=input.read(b,0,1024) > 0)  oSavedFile.write(b,0,nRead);  怎么樣,也很簡(jiǎn)單吧。 接下來(lái)要做的就是整合成一個(gè)完整的程序了。包括一系列的線程控制等等。 斷點(diǎn)續(xù)傳內(nèi)核的實(shí)現(xiàn)主要用了6個(gè)類(lèi),包括一個(gè)測(cè)試類(lèi)。 SiteFileFetch.java負(fù)責(zé)整個(gè)文件的抓取,控制內(nèi)部線程(FileSplitter

10、Fetch類(lèi))。 FileSplitterFetch.java負(fù)責(zé)部分文件的抓取。 FileAccess.java負(fù)責(zé)文件的存儲(chǔ)。 SiteInfoBean.java要抓取的文件的信息,如文件保存的目錄,名字,抓取文件的URL等。 Utility.java工具類(lèi),放一些簡(jiǎn)單的方法。 TestMethod.java測(cè)試類(lèi)。下面是源程序:/*SiteFileFetch.java*/package NetFox;import java.io.*;import .*;public class SiteFileFetch extends Thread S

11、iteInfoBean siteInfoBean = null; /文件信息Beanlong nStartPos; /開(kāi)始位置long nEndPos; /結(jié)束位置FileSplitterFetch fileSplitterFetch; /子線程對(duì)象long nFileLength; /文件長(zhǎng)度boolean bFirst = true; /是否第一次取文件boolean bStop = false; /停止標(biāo)志File tmpFile; /文件下載的臨時(shí)信息DataOutputStream output; /輸出到文件的輸出流public SiteFileFetch(SiteInfoBean

12、 bean) throws IOExceptionsiteInfoBean = 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();elsenStartPos = n

13、ew longbean.getNSplitter();nEndPos = new longbean.getNSplitter();public void run()/獲得文件長(zhǎng)度/分割文件/實(shí)例FileSplitterFetch/啟動(dòng)FileSplitterFetch線程/等待子線程返回tryif(bFirst)nFileLength = getFileSize();if(nFileLength = -1)System.err.println("File Length is not known!");else if(nFileLength = -2)System.err.p

14、rintln("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 = nFileLength;/啟動(dòng)子線程fileSplitterFetch = new FileSplitterFetchnStartPos.length;for

15、(int i=0;i<nStartPos.length;i+)fileSplitterFetchi = new FileSplitterFetch(siteInfoBean.getSSiteURL(),siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(),nStartPosi,nEndPosi,i);Utility.log("Thread " + i + " , nStartPos = " + nStartPosi + ", nEndPos =

16、 " + nEndPosi);fileSplitterFetchi.start();/ fileSplitterFetchnPos.length-1 = new FileSplitterFetch(siteInfoBean.getSSiteURL(),siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(),nPosnPos.length-1,nFileLength,nPos.length-1);/ Utility.log("Thread " + (nPos.length-

17、1) + " , nStartPos = " + nPosnPos.length-1 + ",nEndPos = " + nFileLength);/ fileSplitterFetchnPos.length-1.start();/等待子線程結(jié)束/int count = 0;/是否結(jié)束while循環(huán)boolean breakWhile = false;while(!bStop)write_nPos();Utility.sleep(500);breakWhile = true;for(int i=0;i<nStartPos.length;i+)if(

18、!fileSplitterFetchi.bDownOver)breakWhile = false;break;if(breakWhile)break;/count+;/if(count>4)/ siteStop();System.err.println("文件下載結(jié)束!");catch(Exception e)e.printStackTrace ();/獲得文件長(zhǎng)度public long getFileSize()int nFileLength = -1;tryURL url = new URL(siteInfoBean.getSSiteURL();HttpURLCo

19、nnection httpConnection = (HttpURLConnection)url.openConnection ();httpConnection.setRequestProperty("User-Agent","NetFox");int responseCode=httpConnection.getResponseCode();if(responseCode>=400)processErrorCode(responseCode);return -2; /-2 represent access is errorString sHea

20、der;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);bre

21、ak;elsebreak;catch(IOException e)e.printStackTrace ();catch(Exception e)e.printStackTrace ();Utility.log(nFileLength);return nFileLength;/保存下載信息(文件指針位置)private void write_nPos()tryoutput = new DataOutputStream(new FileOutputStream(tmpFile);output.writeInt(nStartPos.length);for(int i=0;i<nStartPos

22、.length;i+)/ output.writeLong(nPosi);output.writeLong(fileSplitterFetchi.nStartPos);output.writeLong(fileSplitterFetchi.nEndPos);output.close();catch(IOException e)e.printStackTrace ();catch(Exception e)e.printStackTrace ();/讀取保存的下載信息(文件指針位置)private void read_nPos()tryDataInputStream input = new Dat

23、aInputStream(new FileInputStream(tmpFile);int nCount = input.readInt();nStartPos = new longnCount;nEndPos = new longnCount;for(int i=0;i<nStartPos.length;i+)nStartPosi = input.readLong();nEndPosi = input.readLong();input.close();catch(IOException e)e.printStackTrace ();catch(Exception e)e.printSt

24、ackTrace ();private void processErrorCode(int nErrorCode)System.err.println("Error Code : " + nErrorCode);/停止文件下載public void siteStop()bStop = true;for(int i=0;i<nStartPos.length;i+)fileSplitterFetchi.splitterStop();/*FileSplitterFetch.java*/package NetFox;import java.io.*;import .*;pub

25、lic class FileSplitterFetch extends Thread String sURL; /File URLlong nStartPos; /File Snippet Start Positionlong nEndPos; /File Snippet End Positionint nThreadID; /Thread's IDboolean bDownOver = false; /Downing is overboolean bStop = false; /Stop identicalFileAccessI fileAccessI = null; /File A

26、ccess interfacepublic FileSplitterFetch(String sURL,String sName,long nStart,long nEnd,int id) throws IOExceptionthis.sURL = sURL;this.nStartPos = nStart;this.nEndPos = nEnd;nThreadID = id;fileAccessI = new FileAccessI(sName,nStartPos);public void run()while(nStartPos < nEndPos && !bStop)

27、tryURL url = new URL(sURL);HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection ();httpConnection.setRequestProperty("User-Agent","NetFox");String sProperty = "bytes="+nStartPos+"-"httpConnection.setRequestProperty("RANGE",sProper

28、ty);Utility.log(sProperty);InputStream input = httpConnection.getInputStream();/logResponseHead(httpConnection);byte b = new byte1024;int nRead;while(nRead=input.read(b,0,1024) > 0 && nStartPos < nEndPos && !bStop)nStartPos += fileAccessI.write(b,0,nRead);/if(nThreadID = 1)/ Ut

29、ility.log("nStartPos = " + nStartPos + ", nEndPos = " + nEndPos);Utility.log("Thread " + nThreadID + " is over!");bDownOver = true;/nPos = fileAccessI.write (b,0,nRead);catch(Exception e)e.printStackTrace ();/打印回應(yīng)的頭信息public void logResponseHead(HttpURLConnecti

30、on con)for(int i=1;i+)String header=con.getHeaderFieldKey(i);if(header!=null)/responseHeaders.put(header,httpConnection.getHeaderField(header);Utility.log(header+" : "+con.getHeaderField(header);elsebreak;public void splitterStop()bStop = true;/*FileAccess.java*/package NetFox;import java.

31、io.*;public class FileAccessI implements SerializableRandomAccessFile oSavedFile;long nPos;public FileAccessI() throws IOExceptionthis("",0);public FileAccessI(String sName,long nPos) throws IOExceptionoSavedFile = new RandomAccessFile(sName,"rw");this.nPos = nPos;oSavedFile.seek

32、(nPos);public synchronized int write(byte b,int nStart,int nLen)int n = -1;tryoSavedFile.write(b,nStart,nLen);n = nLen;catch(IOException e)e.printStackTrace ();return n;/*SiteInfoBean.java*/package NetFox;public class SiteInfoBean private String sSiteURL; /Site's URLprivate String sFilePath; /Sa

33、ved File's Pathprivate String sFileName; /Saved File's Nameprivate int nSplitter; /Count of Splited Downloading Filepublic SiteInfoBean()/default value of nSplitter is 5this("","","",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 = value;public Strin

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論