0

現在、Binary Diff を書き直してより大きなファイルをサポートしようとしていますGetMem。ファイルの読み取りに使用するとファイル サイズが制限され (おそらく)、それぞれ 900 MB のサイズの 2 つのファイルを読み取ることができないからです。

を使用できると考えましたが、VirtualAlloc残念ながらまだうまくいきませんでした。最初のファイルの割り当ては、見た目からは正常に機能します。2 番目のファイルにメモリを割り当てようとすると、null ポインターが返されます。私はメモリの割り当てにかなり慣れていないので、この質問に既に回答しているスレッドを監督した可能性がある場合はご容赦ください (過去 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;

結局のところ、プログラムを使用して、任意のサイズの 2 つの非テキスト ファイルをバイナリで比較し、そこから Binary Diff を作成したいと考えています。

4

1 に答える 1

4

VirtualAlloc役に立ちません。GetMemこのような大きなメモリ ブロックに対する への呼び出しは、 への呼び出しとして実装されますVirtualAlloc。もちろん、VirtualAllocコードがすべて間違っていることは役に立ちません。とのマッチングVirtualAllocFreeMem本当にダメです。しかし、それVirtualAllocは答えではないので、これについては詳しく説明しません。

あなたの本当の問題は、OS と、プロセスに大きなアドレスを認識させたかどうかに応じて、32 ビット プロセスが 2GB から 4GB のアドレス空間を持っていることです。連続したアドレス空間のギガバイト全体を見つけるのは難しいでしょう。

アドレス空間の連続したブロックを見つけることができないという問題の解決策は、そうしようとするのをやめることです。ファイル全体を一度にメモリに読み込まないでください。小さなブロックを処理しながら、ファイルを 1 つずつ読み取ります。

于 2015-03-02T14:43:09.833 に答える