Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Datenvergleichung


henny - Sa 13.06.09 13:16
Titel: Datenvergleichung
Hallo zusammen,
ich möchte ein Programm schreiben das daten vergleicht!
Das heißt das überbrüft wird ob der inhalt von zwei daten (dateipfäten) vergleicht wird!
Weiß jemand wie das geht?
Danke schonmal im voraus :)


Blackheart666 - Sa 13.06.09 13:23

Was sind (dateipfäten) ?
Und spare nicht immer so an Informationen.


jaenicke - Sa 13.06.09 13:25

Wenn du Dateien auf Gleichheit prüfen willst und es dir einfach machen willst, berechne einfach bei beiden z.B. die MD5 Checksumme. Sonst musst du das eben quasi Byte für Byte via Schleife vergleichen.


SAiBOT - Sa 13.06.09 13:34

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du Dateien auf Gleichheit prüfen willst und es dir einfach machen willst, berechne einfach bei beiden z.B. die MD5 Checksumme. Sonst musst du das eben quasi Byte für Byte via Schleife vergleichen.


kann man eine Checksumme berechnen ohne alle Bytes mit einzubeziehen?


henny - Sa 13.06.09 13:38

Wie berechnet man die MD5 Checksumme? :?:


jaenicke - Sa 13.06.09 13:49

user profile iconSAiBOT hat folgendes geschrieben Zum zitierten Posting springen:
kann man eine Checksumme berechnen ohne alle Bytes mit einzubeziehen?
Nein, deshalb sagte ich einfach, schnell ist es nicht.

Dazu gab es ja glaube ich auch schon Fragen. Entweder hier oder in der DP.

user profile iconhenny hat folgendes geschrieben Zum zitierten Posting springen:
Wie berechnet man die MD5 Checksumme? :?:
Wie wäre es, wenn du danach mal hier im Forum suchst? Du solltest die Datei md5.pas finden, die das macht.


Sirke - Sa 13.06.09 17:12

Zusätzlich muss man bei dem Rat natürlich noch anmerken, dass die Gleichheit nur mit einer gewissen Wahrscheinlichkeit korrekt ist! Diese ist zwar relativ groß, aber nicht zu 100% korrekt. Prüfsummen werden daher auch nicht zur Kontrolle der Gleichheit sondern zum Schutz der Intrgrität eingesetzt.

Von daher wäre wohl eine Byteweise-Überprüfung am sinnvollsten, da in der Regel bereits nach wenigen Bytes eine Ungleichheit bemerkt werden würde und die Schleife vorzeitig verlassen werden kann. Zudem geht die Überprüfung bereits bei der Länge los, welche ein reiner Prüfsummen-Vergleich nicht überprüft.


Delete - Sa 13.06.09 17:22

Streitet Euch ruhig weiter, ich habe die Fragestellung noch gar nicht verstanden. Sollen da 2 Pfade verglichen werden oder die Verzeichnisinhalte oder wirklich Dateien? Fragen über Fragen.


Yogu - Sa 13.06.09 23:54

user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Streitet Euch ruhig weiter, ich habe die Fragestellung noch gar nicht verstanden. Sollen da 2 Pfade verglichen werden oder die Verzeichnisinhalte oder wirklich Dateien? Fragen über Fragen.

Meine Glaskugel sagt mir, dass user profile iconhenny mit daten Dateien meint. Von diesen hat er bis jetzt nur die dateipfäte, die Dateinamen incl. Pfad. Und jetzt will er die beiden Dateien auf Gleichheit überbrüfen.

Und jetzt beantworte ich seine einzige Frage im Anfangspost:

user profile iconhenny hat folgendes geschrieben Zum zitierten Posting springen:
Weiß jemand wie das geht?

Ja. :mrgreen:

Für tiefgreifendere Antworten verweise ich hier auf meine Vorredner sowie auf die Suchen der Entwickle-Ecke, der Delphi-Praxis und Suche bei Google GOOGLE :roll:
Wie kann man nur so ignorant sein...


Webo - So 14.06.09 11:06

Bezogen auf Yogu's Galskugel, bin ich mal so nett und kopiere die Ergebnisse meiner Suche hier hinein:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
function CompareStreams(A,B: TStream):Boolean;
const
  cMaxBuffer = 1024*256;
var
  OldPosA,
  OldPosB: Int64;
  nRead: Integer;
  BufferA,
  BufferB: array[0..cMaxBuffer-1of 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) do
    begin
      if 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:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.Button1Click(Sender: TObject);
var
  FileA,
  FileB: TFileStream;
begin
  FileA := TFileStream.Create('c:\filea.bin', fmOpenRead OR fmShareDenyWrite);
  FileB := TFileStream.Create('c:\fileb.bin', fmOpenRead OR fmShareDenyWrite);
  try
    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;


Ich denke, damit wirst du etwas anfangen können.



//Alternativ gibt es noch das hier, welches aber sehr Speicherfressend seien soll:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function AreFilesEqual(const file1, file2: String): Boolean;
var
  m1, m2: TMemoryStream;
begin
  Result := False;
  m1 := TMemoryStream.Create;
  try
    m1.LoadFromFile(file1);
    m2 := TMemoryStream.Create;
    try
      m2.LoadFromFile(file2);
      if m1.Size = m2.Size then
        Result := CompareMem(m1.Memory, m2.Memory, m1.Size);
    finally
      m2.Free;
    end;
  finally
    m1.Free;
  end
end;