当我将文件加载到内存流时,Delphi内存不足错误

Hos*_*ain 0 memory delphi

我想用Delphi将2GB文件转换为字节数组.我使用这个函数,然后将文件加载到内存Stream中以获取字节.但我得到错误"内存不足".我怎么能解决这个问题?

type
TByteArray  =  Array of Byte;

function StreamToByteArray(Stream: TStream): TByteArray;
begin

// Check stream
if Assigned(Stream) then
begin
// Reset stream position
Stream.Position:=0;
// Allocate size
SetLength(result, Stream.Size);
// Read contents of stream
Stream.Read(result[0], Stream.Size);
end
else
// Clear result
SetLength(result, 0);
end;
//////then in button control i use:
var
strmMem: TMemoryStream;
bytes: TByteArray;
begin
strmMem:=TMemoryStream.Create;
if OpenDialog1.Execute then
strmMem.LoadFromFile(OpenDialog1.FileName);
bytes:=StreamToByteArray(strmMem);
strmMem.Free;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 16

32位进程总共有4GB的地址空间.除非它具有可用的大地址识别标志,否则只有2GB的地址空间可用.

您正在尝试将2GB文件加载到连续的地址空间块中的内存中.你没有机会成功.即使有一个大地址感知4GB地址空间,你也没有希望找到一个连续的2GB地址空间块.

此外,您还尝试将文件读入内存两次,因此实际上需要两个2GB连续块.一个用于流,一个用于数组.这是您使用如下所述的内存流反模式的结果.

一些选择:

  • 切换到64位进程,或
  • 加载整个文件,但在不连续的块中,或
  • 以较小的块一块一块地处理文件.

关于存储器流的使用,这是反复出现的反模式.我要说的是,我们在Delphi Stack Overflow标签中看到的内存流的90%以上是不必要和浪费的.

错误是加载到内存中只是为了能够复制到其他内存.您正在尝试将文件读入数组.所以直接把它读成数组.内存流是没有意义的.使用文件流.从文件流读入数组.这样,您只需将文件的单个副本加载到内存中.

当然,即使进行了这种更改,你也很难将2GB文件放入内存,但你仍然应该只在内存中保存一份数据.