我想用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;
答案 0 :(得分:16)
32位进程总共有4GB的地址空间。除非它具有可用的大地址识别标志,否则只有2GB的地址空间可用。
您正在尝试将2GB文件加载到连续的地址空间块中的内存中。你没有机会成功。即使有一个大地址感知4GB地址空间,你也没有希望找到一个连续的2GB地址空间块。
此外,您还尝试将文件读入内存两次,因此实际上需要两个2GB的连续块。一个用于流,一个用于数组。这是您使用内存流反模式的结果,如下所述。
一些选项:
关于内存流的使用,这是一种反复出现的反模式。我想说,我们在Delphi Stack Overflow标签中看到的> 90%的内存流使用是不必要的和浪费的。
错误是加载到内存中只是为了能够复制到其他内存。您正在尝试将文件读入数组。所以直接把它读成数组。内存流是没有意义的。使用文件流。从文件流读入数组。这样,您只需将文件的单个副本加载到内存中。
当然,即使进行了更改,你也很难将2GB文件放入内存,但你仍然应该只在内存中保存一份数据。