VirtualAlloc - 为大文件分配 space
VirtualAlloc - allocating space for big files
我目前正在尝试重写二进制差异以支持更大的文件,因为使用 GetMem
读取文件会限制文件大小(我想),而且我无法读取 2 个大小为 900 的文件每个 MB。
所以我想,我可以使用 VirtualAlloc
,遗憾的是效果还不是很好。从外观上看,第一个文件的分配工作正常 - 一旦我尝试为第二个文件分配内存,它 returns 一个空指针。不得不说我是分配内存的新手,所以请原谅我,如果我可能已经监督了一个已经回答了这个问题的线程(过去 4 小时我在互联网上搜索了解决方案)。
嗯,这是代码:
procedure TFileData.LoadFile;
var
FileHandle: Integer;
BytesRead: Integer;
dataPoint : Pointer;
begin
FileHandle := FileOpen(fName, fmOpenRead or fmShareDenyWrite);
try
if FileHandle = -1 then
Error('Cannot open file %s', [fName]);
fSize := GetFileSize(FileHandle, nil);
if fSize = Cardinal(-1) then
Error('Cannot find size of file %s - may be to large', [fName]);
if fSize = 0 then
Error('File %s is empty', [fName]);
try
dataPoint := VirtualAlloc(nil,fSize,MEM_COMMIT,PAGE_READWRITE);
fData := dataPoint;
BytesRead := FileRead(FileHandle, fData^, fSize);
if BytesRead = -1 then
Error('Cannot read from file %s', [fName]);
if fSize <> Cardinal(BytesRead) then
Error('Error reading from file %s', [fName]);
except
if Assigned(fData) then
FreeMem(fData, fSize);
raise;
end;
finally
if FileHandle <> -1 then
FileClose(FileHandle);
end;
end;
归根结底,我想使用该程序比较两个任意大小的二进制非文本文件,并从中创建一个二进制差异。
VirtualAlloc
无济于事。您为如此大的内存块调用 GetMem
将作为对 VirtualAlloc
的调用来实现。当然,您的 VirtualAlloc
代码全错了,这无济于事。 VirtualAlloc
和 FreeMem
匹配真的一点都不好。但是,由于 VirtualAlloc
不是答案,我不会详述这个。
您真正的问题是您的 32 位进程的地址 space 介于 2GB 和 4GB 之间,具体取决于您的 OS 以及您是否让进程识别大地址。查找整个千兆字节的连续地址 space 将很棘手。
无法找到地址 space 的连续块问题的解决方案是停止尝试这样做。不要一次将整个文件读入内存。逐段读取文件,处理较小的块。
我目前正在尝试重写二进制差异以支持更大的文件,因为使用 GetMem
读取文件会限制文件大小(我想),而且我无法读取 2 个大小为 900 的文件每个 MB。
所以我想,我可以使用 VirtualAlloc
,遗憾的是效果还不是很好。从外观上看,第一个文件的分配工作正常 - 一旦我尝试为第二个文件分配内存,它 returns 一个空指针。不得不说我是分配内存的新手,所以请原谅我,如果我可能已经监督了一个已经回答了这个问题的线程(过去 4 小时我在互联网上搜索了解决方案)。
嗯,这是代码:
procedure TFileData.LoadFile;
var
FileHandle: Integer;
BytesRead: Integer;
dataPoint : Pointer;
begin
FileHandle := FileOpen(fName, fmOpenRead or fmShareDenyWrite);
try
if FileHandle = -1 then
Error('Cannot open file %s', [fName]);
fSize := GetFileSize(FileHandle, nil);
if fSize = Cardinal(-1) then
Error('Cannot find size of file %s - may be to large', [fName]);
if fSize = 0 then
Error('File %s is empty', [fName]);
try
dataPoint := VirtualAlloc(nil,fSize,MEM_COMMIT,PAGE_READWRITE);
fData := dataPoint;
BytesRead := FileRead(FileHandle, fData^, fSize);
if BytesRead = -1 then
Error('Cannot read from file %s', [fName]);
if fSize <> Cardinal(BytesRead) then
Error('Error reading from file %s', [fName]);
except
if Assigned(fData) then
FreeMem(fData, fSize);
raise;
end;
finally
if FileHandle <> -1 then
FileClose(FileHandle);
end;
end;
归根结底,我想使用该程序比较两个任意大小的二进制非文本文件,并从中创建一个二进制差异。
VirtualAlloc
无济于事。您为如此大的内存块调用 GetMem
将作为对 VirtualAlloc
的调用来实现。当然,您的 VirtualAlloc
代码全错了,这无济于事。 VirtualAlloc
和 FreeMem
匹配真的一点都不好。但是,由于 VirtualAlloc
不是答案,我不会详述这个。
您真正的问题是您的 32 位进程的地址 space 介于 2GB 和 4GB 之间,具体取决于您的 OS 以及您是否让进程识别大地址。查找整个千兆字节的连续地址 space 将很棘手。
无法找到地址 space 的连续块问题的解决方案是停止尝试这样做。不要一次将整个文件读入内存。逐段读取文件,处理较小的块。