作者:为佐殿回来而读书的天使 | 来源:互联网 | 2022-12-09 18:50
我正在尝试下载500 MB以上的文件,因为它的大小会导致内存不足错误.我尝试切换到64位应用程序,它工作.但我需要它在32位应用程序中下载文件.
var
Stream: TStream;
fileStream: TFileStream;
Buffer: PByte;
BytesRead, BufSize: Integer;
Size: int64;
begin
BufSize := 1024;
fileStream:= TFileStream.Create(GetCurrentDir()+'\DownloadFile.zip',
fmCreate);
GetMem(Buffer, BufSize);
Stream := getDownload(size);
if (Size <> 0) then
begin
repeat
BytesRead := Stream.Read(Pointer(Buffer)^, BufSize);
if (BytesRead > 0) then
begin
fileStream.WriteBuffer(Pointer(Buffer)^, BytesRead);
end;
Application.ProcessMessages
until (BytesRead fileStream.Size) then
begin
exit;
end;
end;
finally
FreeMem(Buffer, BufSize);
fileStream.Destroy;
end;
end;
function TServiceMethods.getDownload(out Size: Int64): TStream;
begin
Result := TFileStream.Create(GetCurrentDir+'\DownloadFile.zip', fmOpenRead
or fmShareDenyNone);
Size := Result.Size;
Result.Position := 0;
end;
David Heffer..
5
不要在这里使用内存流.这会强制整个文件进入一个连续的内存块,正如您发现的那样,在32位进程中耗尽内存.
而是将下载的数据直接写入文件.您可以删除中间内存流并直接写入文件流.
当然,所有这些都假设getDownload
在您读取时返回执行下载的流.如果getDownload
将整个文件读入内存流,那么它会遇到与此问题中的代码完全相同的问题.
1> David Heffer..:
不要在这里使用内存流.这会强制整个文件进入一个连续的内存块,正如您发现的那样,在32位进程中耗尽内存.
而是将下载的数据直接写入文件.您可以删除中间内存流并直接写入文件流.
当然,所有这些都假设getDownload
在您读取时返回执行下载的流.如果getDownload
将整个文件读入内存流,那么它会遇到与此问题中的代码完全相同的问题.