亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

用Java實現斷點續傳

2019-11-18 11:33:07
字體:
來源:轉載
供稿:網友

(一)斷點續傳的原理
其實斷點續傳的原理很簡單,就是在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 ();}
}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品mp4| 亚洲跨种族黑人xxx| 国产精品高潮呻吟久久av黑人| 亚洲18私人小影院| 亚洲成人黄色网址| 欧美精品做受xxx性少妇| 国产精品永久免费视频| 亚洲在线观看视频| 国产成人精品久久| 色综合色综合网色综合| 91久久精品久久国产性色也91| 欧美极度另类性三渗透| 欧美国产在线电影| 久久免费精品视频| 亚洲电影成人av99爱色| 色综合久久精品亚洲国产| 国产原创欧美精品| 亚洲国产欧美一区二区三区久久| 欧美性猛交xxxx免费看漫画| 国产精品欧美日韩久久| 国产91成人在在线播放| 日韩欧美在线视频免费观看| 国产一区二区成人| 亚洲精品视频免费| 91理论片午午论夜理片久久| 亚洲free性xxxx护士hd| 色妞色视频一区二区三区四区| 富二代精品短视频| 亚洲丁香婷深爱综合| 中文字幕亚洲欧美| 久久人人爽人人爽爽久久| 97精品欧美一区二区三区| 亚洲精品98久久久久久中文字幕| 亚洲欧美国产va在线影院| 在线观看日韩欧美| 国产一区二区三区在线视频| www.亚洲一区| 欧美性猛交xxxx免费看久久久| 精品国产欧美一区二区三区成人| 91精品久久久久久久久青青| 91av在线网站| 国产一区二区三区在线观看视频| 亚洲国产精品成人av| 国产精品久久久久久av福利软件| 亚洲欧美国产精品专区久久| 亚洲999一在线观看www| 国产国语videosex另类| 欧美成人精品一区| 成人福利免费观看| 国产日韩欧美影视| 欧美日韩亚洲91| 国产mv免费观看入口亚洲| 亚洲精品v天堂中文字幕| 日韩久久免费视频| 国产精品久久久av| 久久久国产精品亚洲一区| 97免费视频在线| 色七七影院综合| 91色视频在线导航| 欧美精品久久久久久久久久| 亚洲国产精品中文| 亚洲成人在线视频播放| 国产精品久久久久高潮| 欧美午夜美女看片| 亚洲人精选亚洲人成在线| 91丨九色丨国产在线| 欧美影院成年免费版| 欧美孕妇孕交黑巨大网站| 午夜精品理论片| 欧美午夜宅男影院在线观看| 亚洲激情中文字幕| 久久精品青青大伊人av| 伊人久久久久久久久久久| 久久人人爽人人爽人人片亚洲| 日韩在线视频中文字幕| 国产91在线播放九色快色| 精品国产一区二区三区久久狼黑人| 亚洲国产精品专区久久| 久久香蕉精品香蕉| 性金发美女69hd大尺寸| 欧美日韩高清在线观看| 国产亚洲视频在线观看| 日产精品99久久久久久| 欧美日韩亚洲国产一区| 国自产精品手机在线观看视频| 国产精品久久久久久超碰| 亚洲成人精品视频| 久久久精品免费视频| 亚洲日韩中文字幕在线播放| 青青草国产精品一区二区| 成人网欧美在线视频| 欧美中文字幕在线| 久久久亚洲国产| 97在线视频免费播放| 国产男人精品视频| 国产91久久婷婷一区二区| 成人久久一区二区三区| 亚洲一区二区福利| 国产亚洲美女精品久久久| 中文字幕欧美日韩在线| 国产一区二区美女视频| 久久久久久久亚洲精品| 国产精品欧美一区二区| 国产精品高潮呻吟久久av无限| 日韩精品在线免费播放| 欧美久久久精品| 日韩视频永久免费观看| 日韩午夜在线视频| 欧美与黑人午夜性猛交久久久| 亚洲欧洲美洲在线综合| 青青精品视频播放| 中文字幕欧美精品在线| 色综合伊人色综合网| 45www国产精品网站| 国产精品一区二区av影院萌芽| 正在播放亚洲1区| 欧美日韩国产在线播放| 亚洲精品久久久久中文字幕二区| 日韩精品在线看| 中文字幕在线看视频国产欧美在线看完整| 国产日韩欧美黄色| 日韩av男人的天堂| 亚洲欧洲成视频免费观看| 精品国产欧美一区二区五十路| 亚洲精品日韩激情在线电影| 国产亚洲精品久久久久久777| 久久久久国产精品免费| 欧美一级电影免费在线观看| 成人网中文字幕| 国产精品免费视频久久久| 亚洲www视频| 国产精品人人做人人爽| 欧美性猛交xxxx乱大交| 亚洲人成啪啪网站| 久久噜噜噜精品国产亚洲综合| 欧美富婆性猛交| 亚洲一区国产精品| 亚洲四色影视在线观看| 欧美一级电影久久| 欧美肥老太性生活视频| 粗暴蹂躏中文一区二区三区| 午夜精品久久久久久久白皮肤| 亚洲欧美一区二区三区四区| 国产高清视频一区三区| 欧美亚洲另类激情另类| 高清视频欧美一级| 国产午夜精品久久久| 国产精品爱啪在线线免费观看| 欧美激情综合亚洲一二区| 美女福利视频一区| 法国裸体一区二区| 久久国产一区二区三区| 国产精品免费久久久久影院| 国产成人在线亚洲欧美| 欧美午夜激情在线| 精品无码久久久久久国产| 亚洲色图五月天| 欧美日本啪啪无遮挡网站| 欧美激情精品久久久久久| 国产精品第8页| 96pao国产成视频永久免费| 在线亚洲国产精品网| 亚洲欧洲日产国产网站| 97热在线精品视频在线观看|