VirtualAlloc - 为大文件分配空间

时间:2015-03-02 14:21:29

标签: delphi delphi-xe6 virtualalloc

我目前正在尝试重写Binary Diff以支持更大的文件,因为使用GetMem来读取文件会限制文件大小(我想)并且我无法读取每个大小为900 MB的2个文件

所以我想,我可以使用VirtualAlloc,但遗憾的是还没有成功。第一个文件的分配工作正常 - 一旦我尝试为第二个文件分配内存,它就会返回一个空指针。要说我对分配内存很新,所以请原谅我,如果我可能已经监督了一个已回答这个问题的帖子(我在过去的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;

在一天结束时,我想使用该程序比较两个任意大小的非文本文件,并从中创建二进制差异。

1 个答案:

答案 0 :(得分:4)

VirtualAlloc无济于事。您对GetMem这么大的内存块的调用将被实现为对VirtualAlloc的调用。当然,您的VirtualAlloc代码完全错误无济于事。将VirtualAllocFreeMem匹配实际上并不是很好。但是,由于VirtualAlloc不是答案,我不会详述。

您真正的问题是您的32位进程的地址空间介于2GB到4GB之间,具体取决于您的操作系统以及是否使您的进程具有大地址识别功能。查找整个千兆字节的连续地址空间将变得棘手。

无法找到连续的地址空间块的问题的解决方案是停止尝试这样做。不要一次将整个文件读入内存。逐个处理较小的块读取文件。