AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Eindeutiger Vergleich für große Dateien gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

Eindeutiger Vergleich für große Dateien gesucht

Ein Thema von dahead · begonnen am 2. Aug 2005 · letzter Beitrag vom 10. Mai 2014
Antwort Antwort
Seite 12 von 12   « Erste     2101112   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#111

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

  Alt 6. Aug 2005, 20:37
Hab zwar den Code zum Dateivergleich noch nicht gefunden, aber ein Stringvergleich tut es doch auch.
Der Dateivergleich entsprach aber in etwa dem Inhalt der "If Length(S2) > 1 Then"-Bedingung.
(hauptsächlich Vergleich der Hash's und bei gleichem Hash nochmal einen byteweisen Vergleich der Daten,
damit das Problem gleicher Hash's, trotz unterschiedlicher Rohdaten nicht auftritt)

"S2 = Wortliste..." führt eine Funktion aus, welche die Bytes vergleicht und beim ersten Unterschied den Vergleich abbricht,
also die gesammten Stringdaten werden fast niemals verglichen/bearbeitet.

Und wenn man jetzt mal die beiden Varianten misst, dann wird eine erhebliche Steigerung der Geschwindigkeit dankt der Hash's auffallen.

Ein Vergleich ohne Hash's ist halt nur dann schneller, wenn nur ein einziger String, oder eben eine einzige Datei mit einem anderen String / einer anderen Datei verglichen wird.
Aber wenn man mehrere Strings/Dateien untereinander vergleicht, sieht das ganz anders aus, da ja sonst jeder String / jede Datei mehrfach eingelesen wird ... beim Hash hat mann dagegen einen netten kleinen Wert zum Vergleich ganz schnell zur Hand.

Warum hier unter Umständen nochmals die Strings/Dateien direkt miteinander Verglichen wird,
brauch ich dank Nico/Hagen ja nichtnochmal zu erklären.
z.B.
Zitat:
Wenn die Prüfsummen gleich sind, müssen die Daten nicht identisch sein.

Input: S
z.B. Inhalt einer TextDatei

Output: Wortliste
Liste aller enthaltenen Wörter
bestehend aus 0-9, A-Z, "_" und a-z


Delphi-Quellcode:
Var S, S2: AnsiString;
  i, i2, i3, L: Integer;
  H: LongWord;
  Wortliste: Array of Record
    Hash: LongWord;
    Wort: AnsiString;
  End;

Begin
  Wortliste := nil;
  L := Length(S);
  While (i <= L) and not (S[i] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i);
  While i <= L do Begin
    i2 := i;
    While (i2 <= L) and (S[i2] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i2);
    S2 := Copy(S, i, i2 - i);
    i := i2;
    If Length(S2) > 1 Then Begin
      H := CRC32(S2);
      i3 := -1;
      For i2 := High(Wortliste) downto 0 do
        If (H = Wortliste[i2].Hash) and (S2 = Wortliste[i2].Wort) Then Begin
          i3 := i2;
          Break;
        End;
      If i3 < 0 Then Begin
        i3 := Length(Wortliste);
        SetLength(Wortliste, i3 + 1);
        Wortliste[i3].Hash := H;
        Wortliste[i3].Wort := S2;
      End;
    End;
    While (i <= L) and not (S[i] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i);
  End;
End;

Delphi-Quellcode:
Var S, S2: AnsiString;
  i, i2, i3, L: Integer;
  Wortliste: Array of AnsiString;

Begin
  Wortliste := nil;
  L := Length(S);
  While (i <= L) and not (S[i] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i);
  While i <= L do Begin
    i2 := i;
    While (i2 <= L) and (S[i2] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i2);
    S2 := Copy(S, i, i2 - i);
    i := i2;
    If Length(S2) > 1 Then Begin
      i3 := -1;
      For i2 := High(Wortliste) downto 0 do
        If S2 = Wortliste[i2].Wort Then Begin
          i3 := i2;
          Break;
        End;
      If i3 < 0 Then Begin
        i3 := Length(Wortliste);
        SetLength(Wortliste, i3 + 1);
        Wortliste[i3] := S2;
      End;
    End;
    While (i <= L) and not (S[i] in ['0'..'9', 'A'..'Z', '_', 'a'..'z']) do Inc(i);
  End;
End;

In etwa so könnte es z.B. für Dateien aussehen:
Delphi-Quellcode:
List: Array of Record
  Hash: LongWord;
  FN: AnsiString;
End;


H := CRC32File(FileName);
i2 := -1;
For i := High(List) downto 0 do
  If (H = List[i].Hash) and CompareFile(FileName, List[i].FN) Then Begin
    i2 := i;
    Break;
  End;
If i2 < 0 Then Begin
  // Datei in die Liste eintragen
  i2 := Length(List);
  SetLength(List, i2 + 1);
  List[i2].Hash := H;
  List[i2].FN := FileName;
End Else Begin
  // eine Datei mit dem selben Inhalt existiert bereits
End;

PS: wie Hagen schon sagte, kann man jetzt noch die Dateigöße mit in den Vergleich mit einbeziehen, um nochmeh Geschwindigkeit rauszubekommen.
Aber so wie mein DemoCode aufgebaut ist, ist dieses nicht wirklich nötig, da ein weiteres Vergleichskriterium die gesammte Prozedur natürlich erstmal etwas verlangsamt
und die erhoffte Beschleunigung nur dann eintreten wird, wenn die Hash's gleich sind ... was ja auch nicht gerade oft vorkommt.
Ergo ist ein weiteres Vergleichskriterium, wie Größe/Datum... hierfür unnötig.
Aber wie gesagt, wenn man wiederum nur eine Datei mit einer anderen Vergleichen will, können witere Kriterien Wunder bewirken

PSS: was ich noch sagen bezöglich der maximalen Dateigröße sagen wollte ...
Viele Dateifunktionen arbeiten nur mit 32 Bit ... und obwohl die netten WinAPI-Funktionen auch 64 Bit verstehen können, wird dennoch (meistens) nur mit 32 Bit gearbeitet.
Also versagen die meisten Hashfunktionen schon bei Dateien über 2 GB.
Die Hashfunktionen mögen ja auch mit mehr als 2 GB umgehen können, aber wenn der Dateiinput dort aufgibt, bringt dieses nun auch nichts.

Und da die Dateien/Datenträger immer größer werden, sind mehr als 2 GB nichts exotisches mehr,
also hab ich meine UCC und demnach dir darin enthaltenen Hashfunktionen natürlich mit 64-Bit ausgestattet.


PS: Ja, das mit dem unverschämten Kopieren ist nicht nett und ich kann sowar ja auch nicht leiden.
Ich bin allerdings der Meinung, das es dabei nicht auf bestimmte Regionen ankommt, wie die Programmierer dort damit umgehen.

In meinem UCC habe ich zwar das Meißte selbst erstellt und an den entsprechenden Stellen, wo es nicht volltändig aus meiner Feder stammt, wird dieses dann auch erwähnt.




[add]
och menno ... immer dieser Hagen mit seinen Geheimnissen ... da denkt man mal, man hat 'nen Fehler in seinen Codes gefunden und dann behauptet der doch tatsächlich, das es angeblich richtig so sei
und wenn man dann die vielen Beiträge dort oben nochmal durchsieht, dann fällt einem auf, daß man sich die Arbeit mit den Codes auch hätte sparen können, weil einiges davon schonmal gesagt wurde

Ich muß unbedingt mal wieder etwas mehr Zeit hier verbringen ... denn bei solchen Themen fällt es doch stark auf, wenn man nicht ständig hier ist ... man kommt einfach nicht mehr hinterher -.-''

so, noch 2 Datei übrig
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von MuTzE.Y85
MuTzE.Y85

Registriert seit: 11. Apr 2006
152 Beiträge
 
#112

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

  Alt 9. Mai 2014, 16:42
Mahlzeit,

der Thread ist schon sehr alt, aber ich habe da trotzdem mal eine Frage
Ich nutze die FileCompare.pas von negaH (Hagen) um 2 Verzeichnisse (A und B) zu Vergleichen, also Datei für Datei.

Dabei nutze ich diese Funktion
Code:
function CompareFile(const FileName1, FileName2: String): Boolean; overload;
begin
  Result := (AnsiCompareText(FileName1, FileName2) = 0) or
            ((GetFileSize(FileName1) = GetFileSize(FileName2)) and
             (HashFile(FileName1) = HashFile(FileName2)) and
             CompareFilePhysical(FileName1, FileName2));
end;
Anschließend werden die unterschiedlichen Dateien synchronisiert (Von A nach B).
Lasse ich nun die Funktion nochmal drüber laufen, findet er wieder Unterschiede (sogar andere Dateien wie vorher), obwohl ich nichts verändert habe.
Nehme ich aber aus der Funktion oben den Teil mit der MD4-Überprüfung raus (HashFile), funktioniert es.

Ist da vielleicht ein Fehler drin
LAN-PC: C2Q Q9550 @ 4004 MHz @ 1.232 V @ Mugen 2 | DFI LANParty JR P45-T2RS | G.Skill 4GB DDR2-1000 CL5 | ZOTAC GTX 280 @ GTX 285 @ 1.06 V | WD Caviar Blue 320GB / WD Caviar Black 640GB | BeQuiet DPP P7 450W | Antec Mini P180
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#113

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

  Alt 9. Mai 2014, 17:18
Ich nutze die FileCompare.pas von negaH (Hagen) um 2 Verzeichnisse (A und B) zu Vergleichen, also Datei für Datei.
...
Ist da vielleicht ein Fehler drin
Die Wahrscheinlichkeit ist eher gering. U.u hast Du eine Kleinigkeit geändert, die sich so auswirkt?
Ich habe mir nicht den ganzen Thread durchgelesen, aber wenn ich es richtig behalten habe geht Hagen von einer bestimmten "üblichen" Konstellation aus.
Ich würde so arbeiten
Code:
if filesize(file1)=filesize(2) then
  if hash(file1)=hash(file2) then
    if binary(file1)=binary(file2) then FileIsEqual
Das AnsiCompareText hat mir nichts gebracht, aber das kann natürlich auch an den Dateiinhalten liegen.

Ändern sich die Inhalte einer Datei nicht, ändert sich auch der Hash-Wert nicht. Falls doch ist da etwas faul. U.U. solltest Du da mal ein Vergleichsprotokoll mitlaufen lassen um zu sehen mit welchen Daten Du da hantierst.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#114

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

  Alt 9. Mai 2014, 17:22
Das AnsiCompare ist ja nur für den Fall, dass man beides Mal den gleichen Dateinamen angibt.
Die sind definitiv gleich, weil diesselbe
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#115

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

  Alt 9. Mai 2014, 17:27
Das kommt davon wenn man nicht richtig liest, Jahre her und trotzdem aufgefallen

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von MuTzE.Y85
MuTzE.Y85

Registriert seit: 11. Apr 2006
152 Beiträge
 
#116

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

  Alt 10. Mai 2014, 00:21
Ich würde so arbeiten
Code:
if filesize(file1)=filesize(2) then
  if hash(file1)=hash(file2) then
    if binary(file1)=binary(file2) then FileIsEqual
Naja die oben genannte Funktion, die ich nutze ist ja aus der FileCompare.pas
Sie wurde also von Hagen dort hinein geschrieben.

Die Wahrscheinlichkeit ist eher gering. U.u hast Du eine Kleinigkeit geändert, die sich so auswirkt?
Darum habe ich mich auch vorsichtig ausgedrückt
LAN-PC: C2Q Q9550 @ 4004 MHz @ 1.232 V @ Mugen 2 | DFI LANParty JR P45-T2RS | G.Skill 4GB DDR2-1000 CL5 | ZOTAC GTX 280 @ GTX 285 @ 1.06 V | WD Caviar Blue 320GB / WD Caviar Black 640GB | BeQuiet DPP P7 450W | Antec Mini P180
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 12 von 12   « Erste     2101112   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz