Prüfen, ob zwei Dateien gleich sind
Folgende Funktion prüft, ob zwei Dateien identisch sind. Als Parameter müssen dieser Funktion die kompletten Dateinamen der zu vergleichenden Dateien übergeben werden. Sie werden dann in einen Stream geladen und per CompareMem verglichen. CompareMem eigent sich sehr gut dazu, Speicherbereiche zu vergleichen. So können beliebige Daten in Streams verglichen werden. Weitere Informationen finden Sie in der OnlineHilfe unter dem Stichwort „CompareMem (Funktion)“.
function AreFilesEqual(const file1, file2: string): Boolean;
var
m1, m2: TMemoryStream;
begin
Result := False;
m1 := nil;
m2 := nil;
try
m1 := TMemoryStream.Create;
m2 := TMemoryStream.Create;
m1.LoadFromFile(file1);
m2.LoadFromFile(file2);
if m1.Size = m2.Size then
Result := CompareMem(m1.Memory, m2.Memory, m1.Size);
finally
m1.Free;
m2.Free;
end
end;
Da die Lösung für große Dateien sehr speicherfressend ist, lädt folgende Funktion immer nur einen Teil in einen internen Puffer und vergleicht diesen. Der Funktion müssen zwei Streams übergeben werden. Sie gibt True zurück, fall die Streams einen identischen Inhalt besitzen:
function CompareStreams(A,B: TStream):Boolean;
const
cMaxBuffer = 1024*256;
var
OldPosA,
OldPosB: Int64;
nRead: Integer;
BufferA,
BufferB: array[0..cMaxBuffer-1] of Byte;
CurPos: Int64;
Size: Int64;
begin
Result := False;
if A.Size B.Size then
Exit;
OldPosA := A.Position;
OldPosB := B.Position;
try
A.Seek(0, soFromBeginning);
B.Seek(0, soFromBeginning);
Size := A.Size;
CurPos := 0;
nRead := cMaxBuffer;
while(CurPos Size-cMaxBuffer then
nRead := Size-CurPos;
A.Read(BufferA, nRead);
B.Read(BufferB, nRead);
if not CompareMem(@BufferA, @BufferB, nRead) then
Exit;
Inc(CurPos, nRead);
end;
Result := True;
finally
A.Seek(OldPosA, soFromBeginning);
B.Seek(OldPosB, soFromBeginning);
end;
end;
Aufgerufen werden kann die Funktion beispielsweise so:
procedure TForm1.Button1Click(Sender: TObject);
var
FileA,
FileB: TFileStream;
begin
FileA := nil;
FileB := nil;
try
FileA := TFileStream.Create('c:filea.bin', fmOpenRead or fmShareDenyWrite);
FileB := TFileStream.Create('c:fileb.bin', fmOpenRead or fmShareDenyWrite);
try
if not CompareStreams(FileA, FileB) then
ShowMessage('Dateien sind ungleich')
else
ShowMessage('Dateien sind gleich :-)');
except
ShowMessage('Es ist ein Fehler beim vergleichen der Streams aufgetreten.');
end;
finally
FileA.Free;
FileB.Free;
end;
end;
