实际上,我正在使用TIdHTTP组件从互联网上下载文件。我想知道是否有可能使用此组件或其他Indy组件暂停和恢复下载。
这是我目前的代码,这可以下载一个文件(没有简历),但是。现在我想暂停下载关闭我的应用程序,当我的应用程序重新启动时,然后从最后保存的位置继续下载。
var
Http: TIdHTTP;
MS : TMemoryStream;
begin
Result:= True;
Http := TIdHTTP.Create(nil);
MS := TMemoryStream.Create;
try
try
Http.OnWork:= HttpWork;//this event give me the actual progress of the download process
Http.Head(Url);
FSize := Http.Response.ContentLength;
AddLog('Downloading File '+GetURLFilename(Url)+' - '+FormatFloat('#,',FSize)+' Bytes');
Http.Get(Url, MS);
MS.SaveToFile(LocalFile);
except
on E : Exception do
Begin
Result:=False;
AddLog(E.Message);
end;
end;
finally
Http.Free;
MS.Free;
end;
end;
2条答案
按热度按时间pobjuy321#
下面的代码对我起作用了。它按块下载文件:
xpszyzbs2#
也许HTTP Range标头可以在这里为您提供帮助。有关恢复HTTP下载的更多信息,请查看archive.org's copy of http://www.west-wind.com/Weblog/posts/244.aspx:
(2004-02-07)几天前,留言板上的一个人问了一个有趣的问题,关于如何提供可恢复的HTTP下载。我对这个问题的第一个回答是,这是不可能的,因为HTTP是一种无状态协议,没有文件指针的概念,因此无法恢复HTTP下载。
然而,事实证明,HTTP1.1确实能够通过使用从客户端发送的http报头中的Range:报头来指定下载范围。您可以执行以下操作:
它下载前100000个字节、超过100000个字节或最后100000个字节的内容。有更多的组合,但前两个是对可恢复下载感兴趣的组合。
为了演示这一特性,我使用wwHTTP(在Web Connection/VFP中)使用HTTPGetEx将文件的第一个400k块下载到一个文件中,目的是模拟中止的下载。接下来,我执行第二个请求,以获取现有文件并下载其余文件:
请注意,此方法使用磁盘上的文件,因此您必须使用HTTPGetEx(带Web连接)。如果您愿意,第二次下载也可以下载到磁盘上,但如果您有多次中止,并且需要将它们拼凑在一起,事情就会变得棘手。在这种情况下,您可能希望跟踪每个文件并向其添加一个数字,然后在最后合并结果。
如果您使用WinInet下载到内存(这是wwHTTP在幕后使用的),您还可以尝试从临时Internet文件缓存中取出文件。虽然这是可行的,但我怀疑这个过程很快就会变得非常复杂,所以如果您计划提供恢复的能力,我强烈建议您使用上面的方法编写输出文件。
这里描述了有关WinInet的一些其他信息以及此方法使用它的一些要求:http://www.clevercomponents.com/articles/article015/resuming.asp。
通过将Range标头添加到wwHTTP:WebRequest.Headers对象,可以对.Net的wwHTTP执行相同的操作。
(Randy Pearson)说你不知道服务器上的文件大小。例如,有没有办法找出这一点,这样你就可以知道要请求多少块?您会先发送Head请求,还是GET响应的Header也会告诉您总大小?
(Rick Strahl)您必须阅读Content-Length:头文件才能获得下载的文件大小。如果您正在恢复,这不应该有什么关系-您只需使用range:(ExistingSize)-来获取其余内容。对于大块的下载,您可以阅读内容长度,并且只下载前x个字节。这在wwHTTP中变得很棘手--您必须使用HTTPGetEx进行单独的调用,并将tnBufferSize参数设置为区块大小,以便在达到该大小后停止检索。
(兰迪·皮尔逊)跟进:看起来一个合规的服务器会发送足够的信息给你,让你知道大小。如果它提供数据块,它应该回复如下内容:
因此,您可以(如果需要)提取它并在循环中使用它,以继续处理智能块请求。
有关同一主题的TIdHTTP相关讨论,还请查看https://forums.embarcadero.com/message.jspa?messageID=219481:
(至少部分按照tfilestream.seek and offset confusion)