TidHTTPServer "Недостаточно памяти" при загрузке большого файла - PullRequest
2 голосов
/ 06 июня 2019

Я использую Delphi 10.3.1 и Indy TIdHTTP / TIdHTTPServer

Я создал клиент-серверное приложение для архивирования файлов.Клиент использует компонент TIdHTTP, код выглядит примерно так:

procedure TForm1.SendFileClick (Sender: TObject);
var
    Stream: TIdMultipartFormDataStream;
begin
    Stream: = TIdMultipartFormDataStream.Create;
    try
       Stream.AddFormField ('field1', 'hello world');
       Stream.AddFile ('field2', 'c:\temp\gigafile.mp4');
       idHTTP.Post ('http://192.168.1.100:1717', Stream);
    finally
       Stream.Free;
    end;
end;

Сервер использует компонент TIdHTTPServer.Казалось, что все работает идеально, пока я не загрузил очень большие видеофайлы (> = 1 ГБ), потому что я получил ошибку «Недостаточно памяти».

При отладке я увидел, что получаю ошибку в функции PreparePostStream (строка1229 модуля IdCustomHTTPServer), когда он вызывает LIOHandler.ReadStream, событие OnCommandGet еще не сработало.

Функция LIOHandler.ReadStream работает неправильно, когда запускается AdjustStreamSize (строка 2013 модуля IdIOHandler)

В моем последнем тесте с большим видеофайлом в функции AdjustStreamSize значение ASize было 1091918544, и я получил ошибку во время выполнения

AStream.Size line: = ASize

Я думаю, что точка началаошибка в модуле System.Classes в следующей процедуре, когда она находится в строке SetPointer ...код.Как я могу решить эту проблему или есть ограничение на размер файлов, которые я могу загрузить с помощью TIdHTTPServer?

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

По умолчанию TIdHTTPServer получает опубликованные данные, используя TMemoryStream, что, очевидно, не будет хорошо работать для таких больших файлов. Вы можете использовать серверное событие OnCreatePostStream для предоставления альтернативного объекта TStream для приема, например TFileStream.

0 голосов
/ 07 июня 2019

Delphi по умолчанию имеет ограничение на использование памяти, добавив следующие строки в файл проекта .DPR:

const
    IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;

    {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

приложения могут использовать до 2,5 ГБ ОЗУ в 32-битных версиях Windowsи до 3,5 ГБ оперативной памяти на 64-битных версиях.(https://cc.embarcadero.com/item/24309)

В любом случае, я думаю, что решение @RemyLebeau - лучшее

...