TidHttp uploads files flushes memory exception

Consider the following code downloading a file from the Internet using Indy components:

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; 

I am getting a memory exception. It happens that in addition to the fact that I use TFileStream , the bytes that are written to it do not go directly to the disk, instead they remain in memory until get is completed.

The file I'm trying to download is really very large.

Does anyone know how to load a large file without exception from memory?

Delphi 2010 and the latest Indy 10 from Indy SVN.

EDIT

This is not a FileStream problem. This is an Indy problem. Indy somehow caches the file in memory before writing to the stream.

+4
source share
3 answers

TIdHTTP loads the entire file into memory if the data is compressed, or if the data is HTML, and the TIdHTTP.HTTPOptions property TIdHTTP.HTTPOptions not contain the hoNoParseMetaHTTPEquiv flag.

Indy does not yet support streaming decompression for HTTP (this is for FTP, though), so TIdHTTP caches all compressed data in memory before it can decompress it into a file.

HTML analysis is sometimes necessary in cases where HTML overrides the values โ€‹โ€‹of HTTP headers with new values โ€‹โ€‹through HTML <meta> tags, which is the most important value of Charset data, so TIdHTTP can decode data using the correct encoding when the data is returned to the user code as String . Enabling the hoNoParseMetaHTTPEquiv flag disables this parsing and thus caching of HTML data (unless compression is used).

+5
source

I figured out this problem. I used the server side Indys ServeFile function.

This function checks if the Content-Type parameter has been specified, and if not, it automatically detects the Content-Type . The problem was that I did not change the Content-Type , and the default was text / html. Changing the content type made the client write directly to the stream.

I think the ServeFile function should always set the correct Content-Type to avoid such problems.

On the client side, I found out this code, which helped me a lot:

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

Did you try to download the file in parts by setting Request.ContentRangeStart and Request.ContentRangeEnd ?

+1
source

Source: https://habr.com/ru/post/1412645/


All Articles