Reputation: 19
I'm trying to download a file of 500 mb more when it's in this size gives out of memory error. I tried switching to 64 bit application and it worked. But I would need it to work in 32 bit application to download file.
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 < BufSize);
if (Size <> 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;
Upvotes: 0
Views: 607
Reputation: 612884
Don't use a memory stream here. That forces the entire file into a contiguous block of memory, which as you discovered exhausts memory in a 32 bit process.
Instead, write the downloaded data directly to file. You can remove the intermediate memory stream and write directly to a file stream.
Of course, all of this assumes that getDownload
returns a stream that performs the download as you read it. If getDownload
reads the entire file into a memory stream then it suffers from the exact same problem as the code in this question.
Upvotes: 5