Delphi用ICS控件進行斷點續傳多線程
原帖地址:http://www.lonetear.net/bbs/read.asp?id=36143url
原帖地址2(傻貓):http://www.samool.com/archives/41252/.net
用HTTPCLI和NMHTTP均可以實現斷點續傳,原理都同樣,可是因爲HTTPCLI支持帶用戶名和密碼的HTTP代理,NMHTTP不支持,HTTPCLI還支持SOCK四、SOCK5代理,所以我選用HTTPCLI來實現。
主要是經過HTTPCLI的ContentRangeBegin和ContentRangeEnd屬性來控制,ContentRangeBegin是指從哪一個字節開始下載,ContentRangeEnd是指下載到哪一個字節爲止,若是留空則表示下載到文件結束。例如
httpcli1.ContentRangeBegin:='100'; //從100字節的位置開始下載
httpcli1.ContentRangeEnd:='200'; //下載到200字節的地方中止
httpcli1.ContentRangeBegin:='100'; //從100字節的位置開始下載
httpcli1.ContentRangeEnd:=''; //下載到文件結束
看下面的例子
var
f:TSearchRec;
FindFirst(fname,faAnyFile,f);
httpcli1.ContentRangeBegin:=inttostr(f.Size);
httpcli1.ContentRangeEnd:='';
Httpcli1.RcvdStream:=TFileStream.Create(fname,fmOpenReadWrite);
httpcli1.url:='xxxxxxx';//一個URL地址
httpcli1.Get;
Httpcli1.RcvdStream.Destroy;
Httpcli1.RcvdStream:= nil;
很奇怪的是,用了上面的語句,續傳是續傳了,可是續傳的內容老是把先前的內容覆蓋了,開始覺得是Httpcli1.RcvdStream:=TFileStream.Create(fname,fmOpenReadWrite);中fmOpenReadWrite參數的問題,換完了全部的參數問題依舊,後來在網上看到一些相關的C++例程,受到一點啓發,其實續傳的代碼沒有錯,錯在對文件的處理上,當TFileStream.Create以後,文件指針的位置默認是文件開頭,應當把文件指針指向結尾,修正後的代碼以下:
var
fs:TFileStream;
fs:=TFileStream.Create(fname,fmOpenReadWrite);
fs.Position:=fs.size; //將文件指針移到文件的結尾,用SEEK也可實現
httpcli1.ContentRangeBegin:=fs.Size;
httpcli1.ContentRangeEnd:='';
Httpcli1.RcvdStream:=fs;
httpcli1.url:='xxxxxxx';//一個URL地址
httpcli1.Get;
fs.free;
用以上的代碼徹底能夠實現斷點續傳,目前還有一個問題沒有解決,若是下載的URL是一個動態腳本的話,例如ASP文件,在ASP文件中若是發生了
response.redirect使URL動態改變,斷點續傳就沒法實現,在HTTPCLI的locationchange事件中showmessage(httpcli1.url);發現雖然ASP文件中用REDIRECT改變了URL,可是HTTPCLI的URL並無更新,估計這是沒法續傳的緣由。
歡迎你們繼續討論。 ------------------------------------------------
線程
如今的下載軟件通常都是多線程,多資源的下載模式,本文用ICS中的TMultipartHttpDownloader組件實現多線程,單資源的分塊下載模式,魯大師的升級就是這樣的原理,能夠參考.
先看組件的幾個事件:
HTTPRequestDone(Sender: TObject; ErrorCode: Integer; const Reason: string);
下載完成事件,在這裏能夠釋放下載的文件流
FMultiPartHTTP.FileStream.Free;
FMultiPartHTTP.FileStream := nil;
HTTPShowStats(Sender: TObject);
下載顯示狀態信息事件
'已下載(MB):' + Format('%2f',[FMultiPartHTTP.TotalCount / 1024 / 1024]) +
' 完成:' + Format('%3.0f', [FMultiPartHTTP.PercentDone])+'%' +
' 速度(KB/秒):' + Format('%6.2f', [FMultiPartHTTP.CurSpeed]) +
' 耗時:' + FormatDateTime('hh:nn:ss', FMultiPartHTTP.ElapsedTime);
下面2個事件和進度條有關,ICS自帶了個下載進度條
HTTPProgressAddSegment(Sender: TObject; StartOffset, ASpan, InitPos: Int64);
ASpan分段大小,InitPos分段開始大小, StartOffset,分段開始大小
HTTPProgressSetPosition(Sender: TObject;Index: Integer; Position: Int64);
Index第幾個分段 Position 分段已下載的大小
下面是用法,很是簡單:
FMultiPartHTTP.URL:=下載文件地址;
FMultiPartHTTP.PartCount:=分塊個數;
FMultiPartHTTP.FileStream:=TFileStream.Create('下載本地文件名',fmCreate);
FMultiPartHTTP.Start;
注意:PartCount要大於1,這個組件支持斷網斷點下載,若是要控制下載的線程數量須要改ICS的源代碼代理