如何通过TIdHTTP下载大文件?

5

我使用这段代码来下载小文件:

Var
 ms:TMemoryStream;
begin
  ms:=TMemoryStream.Create;
  Idhttp1.get('http://mydomain.com/myfile.zip',ms);
  ms.SaveToFile('myfile.zip');
  ms.Free;
end;

但是文件在存储到磁盘之前会先保存在RAM中,因此下载超过1GB的文件可能会很困难。有没有一种按部分下载文件的方法?或者我需要使用WinInet吗?提前感谢!


3
最简单的选择是使用 TFileStream 而不是 TMemoryStream,这将直接将文件写入磁盘中,而不是在下载时存储在内存中。IdHTTP.Get 只需要一个 TStream 参数,这意味着你可以提供任何类型的流给它。 - Ken White
1
就像@Ken所说的那样,只需将TMemoryStream替换为TFileStream即可。无论如何,不要忘记使用try..finally块来确保流被释放。你的代码最终可能会被修改成类似这样 - TLama
1个回答

13

TMemoryStream 提供了一个内存缓冲区,因此如果您把下载内容写入其中,您需要有足够的内存来保存所有接收到的数据。然而,它并不是唯一一种流类型。您可以使用任何类型的流,包括将内容在接收时写入磁盘的流。例如,可以使用TFileStream

var
  s: TStream;

s := TFileStream.Create('myfile.zip', fmCreate);
try
  IdHttp1.Get(..., s);
finally
  s.Free;
end;

在任何情况下,如果您在 TMemoryStream 上调用 LoadFromFileSaveToFile,那么可能更适合使用 TFileStream


7
如果Get()失败,我会进一步使用额外的try/except来在调用s.Free()后删除文件。根据您展示的代码,如果下载失败,该文件不会被删除。除非你想支持断点续传,否则请删除该文件。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接