Einzelnen Beitrag anzeigen

Benutzerbild von dahead
dahead

Registriert seit: 16. Mai 2005
620 Beiträge
 
#53

Re: Eindeutiger Vergleich für große Dateien gesucht

  Alt 3. Aug 2005, 13:28
Ja, das stimmt. bei meinem system ist der durch GetSystemAllocationGranularity ermittelte buffer sogar genau 64 kb groß.

das TMemoryMappedFile erstelle ich durch eine leicht von deiner version abgewandelte prozedur (ich habe mir z.b. die property fSize eingebaut):

Delphi-Quellcode:
constructor TMemoryMappedFile.Create(const FileName: String);
var
  P: Pointer;
begin
  fFileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);

  if fFileHandle = INVALID_HANDLE_VALUE then
   raise Exception.Create(Format('Datei %s konnte nicht geöffnet werden!', [Filename]));

 //if fFileHandle > 0 then
 if fFileHandle <> INVALID_HANDLE_VALUE then
  begin
   fSize := GetFileSize(fFileHandle, nil);
   if fSize > 0 then
    begin
     fFileMap := CreateFileMapping(fFileHandle, nil, PAGE_READONLY, 0, 0, nil);
     {
    if fFileMap <> 0 then
      begin
      P := MapViewOfFile(
        fFileMap,
        FILE_MAP_READ,
        0,    // beginn der map
        0,    //
        0);  // zu lesende bytes, fSize liest kompl. Datei ein

      if P <> nil then
        inherited SetPointer(P, fSize);
      end;
      }


    end;
  end;

  inherited Create;
end;
wie du siehst, frage ich im create nicht MapViewOfFile ab, da ich dies erst beim vergleich mache.

hier die vergleichs prozedur:

Delphi-Quellcode:
function Tmf.CompareMemoryMappedFiles(const File1, File2: String): Boolean;
var
  MMF1, MMF2: TMemoryMappedFile;
  P1, P2: Pointer;
  CurPos: Int64;
  AllocGran: Cardinal;
begin
  Result := False;
  AllocGran := GetSystemAllocationGranularity; //Todo: hier raus nehmen, nicht bei jedem aufruf erneut abfragen
  MMF1 := TMemoryMappedFile.Create(File1);
  MMF1.Position := 0;
  try
    MMF2 := TMemoryMappedFile.Create(File2);
    MMF2.Position := 0;
    try
      begin
       CurPos := 0;
       while CurPos < MMF1.Size do
        begin
         P1 := MapViewOfFile(MMF1.fFileMap, FILE_MAP_READ, CurPos, CurPos + AllocGran, AllocGran);
         P2 := MapViewOfFile(MMF2.fFileMap, FILE_MAP_READ, CurPos, CurPos + AllocGran, AllocGran);
         if not CompareMem(P1, P2, AllocGran) then //hier kriege ich die AV
          Exit;
         Inc(CurPos, AllocGran);
        end;
       Result := True;
      end;
    finally
      MMF2.Free;
    end;
  finally
    MMF1.Free;
  end;
end;
allerdings bekomme ich bei CompareMem eine AV. ich glaube ich übergebe entweder die Length von Comparemem nicht korrekt oder es hapert bereits bei der P1, P2 pointer zuweisung.

mein problem ist auch, dass ich durch MapViewOfFile nicht die Length kenne. daher übergebe ich AllocGran.
  Mit Zitat antworten Zitat