断点续传 流 I/O Indy (100分)

  • 主题发起人 主题发起人 tuti
  • 开始时间 开始时间
T

tuti

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在正在学习,如果制作断点续接的程序,
让服务器端指定位置下载到挺容易(资料很多)。

用clientSocket自己实现http协议觉得麻烦,
就想使用indy的IdHTTP控件来实现。
可指定以下IDHTTP的以下2个属性,来实现指定
下载范围的功能。
IdHTTP1.Request.ContentRangeStart
IdHTTP1.Request.ContentRangeEnd


但在client端,处理I/O却遇到了麻烦。

以下几个主要代码片断:
fResponse:= TMemoryStream.Create; //建立返回结果流

IdHTTP1.Get(fHttpurl,fResponse); //取得get方法

//建立文件流
fSaveFile:= TFileStream.Create(fDownloadPath+'/'+EdtSaveAs.Text,fmCreate);

GetMem( p, 1024); //建立临时数据块

n:= fResponse.Read( p^, n ); //何返回总是0,?????

fSaveFile.WriteBuffer( p^, n ); //写入文件流中
环境:
win2000 sp2
Delphi 6.0
ICS为Delphi 6.0自带版本

原来设想:
由于indy的文档说,它是建立在blockSocket之上,所以我原想
用类似java中,一个流套在另一个流对象上的做法来实现。

fResponse取得get返回流对象后,用TStream.read()方法来,
将数据每次以 1024的长度读取,然后写入文件流中,并可
记录下目前的已经下载位置,以便断点续传时申请用。


出现问题:
1.fResponse似乎一次就将全部内容读入,而不是分批读取。
那样对下载大文件就没有意义了。

2.fResponse.Read( p^, n )的返回值应为实际读取长度,
取得返回值是主要担心网络状况不好,取得的数据块长度,未必符合期望长度。
但返回总是0,迷盲。

3.不理会read返回值,按理想状态写文件。
完成写入文件流后,得到内容无法识别。下载TXT文件,但得到内容无法辨认。

4.调试过程中,debug窗口中,fResponse.size始终为0,
但showmessage(IntToStr(fResponse.size))却显示实际下载文件长度。
debug提示和实际数据不一致,不知是何原因。

目前只能先将就着用
fResponse.SaveToFile(fDownloadPath+'/'+EdtSaveAs.Text);
没有多大实际意义。


请各位高手指教!
 
LDestStream := TFileStream.Create(FCurrFile, fmOpenWrite);
LDestStream.Seek(DownPos,soFromBeginning);
FHttp.Request.ContentRangeStart:=DownPos;
FHttp.Request.ContentRangeEnd:= EndPos;
FHttp.Get(FCurrUrl,LDestStream);
FreeAndNil(LDestStream);
 
谢谢 codehunter,但我觉得这些代码,并不足已解决断点续接的实际问题。
我认为断点续接的实现,有以下几个方面的问题:
对于"断点续传"功能的实现,需要client端和server端共同配合完成。
(1)首要条件是Server端,提供就一个可以允许下载的文件,
指定其下载的开始位置与结束的位置的功能。
(2)Client端需要能向相应Server端发送特定格式的请求消息。
(3)Client端需要能将分批下载的文件块,能重新合并成原文件。
(4)网络传输中断时,Client端需要侦知已有效接受的文件长度,
以便向Server端请求就断点处起重新传输文件。
(5)如需要多线程下载,需要Client端程序有多线程能力。
(Server端一般都能同时响应多个连接)
我认为实际运用中的主要问题在于问题(4)。
因为经常面临下载几百M到上G的的任务。显然不能直接读入到内存中,
CODEHUNTER的方法,其实有个前提,那就是必须已经知道断点的位置。
但如果返回流,直接套接在文件流上,在读写过程中又怎么能知道出现
断点的位置呢?读取已经下载的文件长度?这办法好象粗糙了点。
我原先想找一个在返回流中,分段读取数据的方法。
不知道有什么办法。
 
接受答案了.
 
后退
顶部