TidHttp文件下载trows内存不足异常

时间:2012-05-15 19:10:55

标签: delphi file download delphi-2010 indy

考虑使用Indy组件从Internet下载文件的以下代码:

procedure TForm26.Button1Click(Sender: TObject);
var
  vFileStream : TStream;
begin
  DeleteFile('C:\test.exe');
  vFileStream := TFileStream.Create('C:\test.exe', fmCreate);
  IdHTTP1.Get('SomeUrl', vFileStream);
  vFileStream.Free;
end;

我收到了Out of memory异常。发生的事情是,除了我使用TFileStream的事实之外,写入它的字节不直接进入磁盘,而是在get终止之前保留在内存中。

我试图下载的文件确实很大。

有没有人知道如何在没有内存不足的情况下下载大文件?

Delphi 2010和来自Indy的SVN的最新Indy 10。

修改

这不是FileStream问题。这是一个Indy问题。不知何故,Indy在写入流之前将文件缓存在内存中。

3 个答案:

答案 0 :(得分:5)

如果数据被压缩,或者数据是HTML且TIdHTTP属性不包含TIdHTTP.HTTPOptions标志,

hoNoParseMetaHTTPEquiv会将整个文件下载到内存中。

Indy还不支持HTTP的流式解压缩(不过它适用于FTP),因此TIdHTTP会将整个压缩数据缓存到内存中,然后才能将其解压缩到文件中。

在HTML通过HTML <meta>标记覆盖带有新值的HTTP标头值,最重要的是数据的Charset值,有时需要解析HTML,因此TIdHTTP可以使用正确的字符集解码数据当数据作为String返回到用户的代码时。启用hoNoParseMetaHTTPEquiv标志会禁用该解析,从而禁用HTML数据的任何缓存(除非也使用压缩)。

答案 1 :(得分:3)

我发现了这个问题。我在服务器端使用了Indys ServeFile功能。

此功能检查是否指定了Content-Type,如果没有,则会自动检测Content-Type。问题是我没有更改Content-Type,默认情况下是text / html。更改内容类型使客户端直接写入流。

我认为serveFile函数应始终设置正确的Content-Type以避免此类问题。

在客户端,我发现这段代码给了我很多帮助:

  LParseHTML := IsContentTypeHtml(AResponse) and Assigned(AResponse.ContentStream) and not (hoNoParseMetaHTTPEquiv in FOptions);
  LCreateTmpContent := LParseHTML and not (AResponse.ContentStream is TCustomMemoryStream);

答案 2 :(得分:1)

您是否尝试通过设置Request.ContentRangeStartRequest.ContentRangeEnd

来部分下载文件