Einzelnen Beitrag anzeigen

Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: 2 Textdateien vergleichen

  Alt 24. Sep 2020, 13:54
Und folgender Algorithmus ist fehlerhaft.
...mein schnippsel von oben...
Genauer gesagt liefert dieser nur beim Rückgabewert False ein korrektes Ergebnis. Der Rückgabewert True ist unbrauchbar, denn es fehlt noch der Byteweise Vergleich.
Ein Hash wird über die Bytes generiert.
Hättest Du die Güte ein Beispiel zu posten damit das was Du sagst nachvollziehbar ist?
Das 2 unterschiedliche Dateien den gleichen MD5 Hash liefern... möglich ja aber eher die Ausnahme als die Regel.

Ich hatte halt Geschwindigkeit im Vordergrund.

so etwas hier wollte ich verhindern...
gefunden auf Stackoverflow, code von David
Delphi-Quellcode:
// Usage example

var lError: Integer;
...
 if FilesAreIdentical(lError, 'file1.ext', 'file2.ext')
    then Memo1.Lines.Append('Files are identical.')
    else case lError of
           0: Memo1.Lines.Append('Files are NOT identical!');
           1: Memo1.Lines.Append('Files opened, stream read exception raised!');
           2: Memo1.Lines.Append('File does not exist!');
           3: Memo1.Lines.Append('File open exception raised!');
         end; // case
...

// StreamAreIdentical

function StreamsAreIdentical(var aError: Integer;
                             const aStream1, aStream2: TStream;
                             const aBlockSize: Integer = 4096): Boolean;

var
  lBuffer1: array of byte;
  lBuffer2: array of byte;
  lBuffer1Readed,
  lBuffer2Readed,
  lBlockSize: integer;

begin
  Result:=False;
  aError:=0;
  try
    if aStream1.Size <> aStream2.Size
       then Exit;

    aStream1.Position:=0;
    aStream2.Position:=0;

    if aBlockSize>0
       then lBlockSize:=aBlockSize
       else lBlockSize:=4096;

    SetLength(lBuffer1, lBlockSize);
    SetLength(lBuffer2, lBlockSize);

    lBuffer1Readed:=1; // just for entering while

    while (lBuffer1Readed > 0) and (aStream1.Position < aStream1.Size) do
    begin
      lBuffer1Readed := aStream1.Read(lBuffer1[0], lBlockSize);
      lBuffer2Readed := aStream2.Read(lBuffer2[0], lBlockSize);

      if (lBuffer1Readed <> lBuffer2Readed) or ((lBuffer1Readed <> lBlockSize) and (aStream1.Position < aStream1.Size))
         then Exit;

      if not CompareMem(@lBuffer1[0], @lBuffer2[0], lBuffer1Readed)
         then Exit;
    end; // while

    Result:=True;
  except
    aError:=1; // stream read exception
  end;
end;


// FilesAreIdentical using function StreamsAreIdentical

function FilesAreIdentical(var aError: Integer;
                           const aFileName1, aFileName2: String;
                           const aBlockSize: Integer = 4096): Boolean;

var lFileStream1,
    lFilestream2: TFileStream;

begin
 Result:=False;
 try
   if not (FileExists(aFileName1) and FileExists(aFileName2))
      then begin
        aError:=2; // file not found
        Exit;
      end;

   lFileStream1:=nil;
   lFileStream2:=nil;
   try
     lFileStream1:=TfileStream.Create(aFileName1, fmOpenRead or fmShareDenyNone);
     lFileStream2:=TFileStream.Create(aFileName2, fmOpenRead or fmShareDenyNone);
     result:=StreamsAreIdentical(aError, lFileStream1, lFileStream2, aBlockSize);
   finally
     if lFileStream2<>nil
        then lFileStream2.Free;

     if lFileStream1<>nil
        then lFileStream1.Free;
   end; // finally
 except
   aError:=3; // file open exception
 end; // except
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat