考虑使用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在写入流之前将文件缓存在内存中。
答案 0 :(得分:5)
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)