我想用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;
最佳答案
一个32位进程共有4GB的地址空间。除非它具有大的地址识别标志,否则只有2GB的地址空间可供使用。
您正在尝试在连续的地址空间块中将2GB文件加载到内存中。您不可能成功。即使具有大的地址感知4GB地址空间,您也几乎没有希望找到连续的2GB地址空间块。
此外,您还尝试将文件读入内存两次,因此实际上需要两个2GB连续块。一个用于流,另一个用于数组。这是由于您使用了如下所述的内存流反模式。
一些选项:
切换到64位进程,或
加载整个文件,但以不连续的块加载,或
以较小的块为单位逐个处理文件。
关于内存流的使用,这是重复出现的反模式。我想说的是,我们在Delphi Stack Overflow标签中看到的90%以上的内存流使用都是不必要和浪费的。
错误是加载到内存中只是为了能够复制到其他内存中。您正在尝试将文件读入数组。因此,将其直接读入数组。内存流毫无意义。使用文件流。从文件流读取到数组。这样,您只需将文件的单个副本加载到内存中。
当然,即使进行了这种更改,您仍然很难将2GB的文件放入内存中,但是您仍然应该致力于仅将一个数据副本保存在内存中。
关于delphi - 我将文件加载到内存流时出现Delphi内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34801278/