TidHTTPServer“内存不足”,上传大文件

时间:2019-06-06 12:40:54

标签: http delphi indy idhttp

我正在使用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组件。 在我上传非常大的视频文件(> = 1GB)之前,一切似乎都可以正常工作,因为出现了“内存不足”错误。

通过调试,我看到当它调用LIOHandler.ReadStream时,我在函数PreparePostStream(IdCustomHTTPServer单元的第1229行)中收到错误,事件OnCommandGet尚未触发。

函数LIOHandler.ReadStream在运行AdjustStreamSize时出错(IdIOHandler单元的2013行)

在上一个具有较大视频文件的测试中,在AdjustStreamSize函数中,ASize的值为1091918544,执行

时出现错误。
AStream.Size line: = ASize

在SetPointer ...行中,我认为错误的起点在以下过程的System.Classes单元中。

procedure TMemoryStream.SetCapacity (NewCapacity: NativeInt);
{$ IF SizeOf (LongInt) = SizeOf (NativeInt)}
begin
  SetPointer (Realloc (LongInt (NewCapacity)), FSize);
  FCapacity: = NewCapacity;
end;

我在网上阅读了许多文章,但是我不明白我的代码是否有问题。 我该如何解决,或者可以通过TIdHTTPServer上传的文件大小没有限制?

2 个答案:

答案 0 :(得分:2)

默认情况下,TIdHTTPServer使用TMemoryStream接收发布的数据,这显然不适用于如此大的文件。您可以使用服务器的OnCreatePostStream事件来提供要接收的备用TStream对象,例如TFileStream

答案 1 :(得分:-1)

Delphi默认情况下似乎对内存使用量有某种限制,请将以下行添加到.DPR项目文件中:

const
    IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;

    {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

应用程序在Windows 32位版本上最多可以使用2.5 GB RAM,在64位版本上最多可以使用3.5 GB RAM。 (https://cc.embarcadero.com/item/24309

无论如何,我认为@RemyLebeau解决方案是最好的