支持者
当 HTTP 客户端发送 multipart/form-data 流时,服务器会将该流保存在内存中。当文件较大时,服务器可能会发生内存不足异常。为避免这些异常,服务器提供了一个名为 HTTPUploadFiles 的属性,您可以在其中配置如何处理 POST 流:在内存中处理还是作为文件流处理。如果将这些流作为文件流处理,则接收到的流会直接存储到硬盘中,从而避免内存问题。
若要将服务器配置为将 multipart/form-data 流保存为文件流,请按照以下步骤操作:
1. 设置属性 HTTPUploadFiles.StreamType = pstFileStream。使用此设置后,服务器会将这些流存储到硬盘中。
2. 您可以配置将文件存储为文件流的最小字节大小。默认值为零,这意味着所有流都将存储为文件流。
3. 使用 SaveDirectory 指定存储流的文件夹,如果未设置,则它们将存储在应用程序所在的同一文件夹中。
4. 当客户端发送 multipart/form-data 时,内容会被编码在边界(boundaries)内,如果启用了 RemoveBoundaries 属性,则在完整接收流之后,会自动提取边界内的内容。
示例代码
首先创建一个新的服务器实例,并设置将流保存为文件流。
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;
然后使用以下配置创建一个新的 html 文件
<html>
<head><title>sgcWebSockets - Upload Big File</title></head>
<body>
<form action="http://127.0.0.1:5555/file" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
<input type="file" name="file_1" />
<input type="submit" />
</form>
</body>
</html>
最后,使用 Web 浏览器打开该 html 文件,并向服务器发送一个文件。服务器将创建一个扩展名为“.sgc_ps”的新文件流,当流完全接收后,它会从边界中提取该文件。
有 2 个事件可用于自定义上传文件流程(要求启用 HTTPUploadFiles.RemoveBoundaries 属性)
OnHTTPUploadBeforeSaveFile
该事件在文件保存之前触发,允许自定义所接收文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
if aFileName = "test.jpg" then
aFileName := "custom_test.jpg";
end;
OnHTTPUploadAfterSaveFile
该事件在文件保存之后触发,允许您获知所保存文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName);end;
OnHTTPUploadReadInput
当解码器读取到与文件输入不同的输入值时(例如:如果表单包含 name、date 等一些变量),会触发该事件。
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue);end;