【问题标题】:Delphi out of memory error when i load file to memory stream当我将文件加载到内存流时,Delphi 内存不足错误
【发布时间】:2016-01-14 22:51:09
【问题描述】:

我想用 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;

【问题讨论】:

  • 为什么要在内存中保存这么大的文件? (两次)。

标签: delphi memory


【解决方案1】:

一个 32 位进程总共有 4GB 的地址空间。除非它有大地址感知标志可用,否则只有 2GB 的地址空间可供它使用。

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

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

一些选项:

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

关于内存流的使用,这是一个反复出现的反模式。我想说,我们在 Delphi Stack Overflow 标记中看到的内存流的使用超过 90% 是不必要和浪费的。

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

当然,即使进行了更改,您仍然难以将 2GB 的文件放入内存,但您仍然应该致力于在内存中仅保存一份数据副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多