Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 01.10.08 11:05
Ich will viele Dateien möglichst schnell vergleichen
Dazu habe ich die Möglichkeiten:
Dateigröße
DateiDatum
Binärvergleich
Kennt jemand da schnelle Routinen?
Habe z.zt. diese:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| if (FindFirst(source,faAnyFile,F1)=0) and (FindFirst(target,faAnyFile,F2)=0) then begin try fsize1:=F1.FindData.nFileSizeLow or (F1.FindData.nFileSizeHigh shl 32); If(fsize1=(F2.FindData.nFileSizeLow or (F2.FindData.nFileSizeHigh shl 32))) then If((F1.FindData.ftLastWriteTime.dwLowDateTime=F2.FindData.ftLastWriteTime.dwLowDateTime) and (F1.FindData.ftLastWriteTime.dwHighDateTime=F2.FindData.ftLastWriteTime.dwHighDateTime)) then ... |
und als Binärvergleich:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| 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); except end; m1.Free; m2.Free; |
Gibt es schnellere Varianten?
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Mi 01.10.08 11:08
Zu deinem Binärvergleich:
Du könntest mit einem TFileStream z.B. immer nur 8kb Blöcke laden und diese vergleichen - dann musst du nicht sofort die komplette Datei auslesen.
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 01.10.08 11:11
ok...kling gut
wie mache ich das?
find die funktion grade ne..das was ich gefunden hab würde zwar kleinere blöcke vergleichen aber trotzdem die ganze datei einlesen...
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mi 01.10.08 11:24
Was ist denn das Ziel deines Vergleiches?
Musst du wirklich die Datei-Inhalte vergleichen, wenn Datei-Datum und -Größe schon geprüft wurden?
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 01.10.08 11:31
Datum und Größe sind sehr unzuverlässig. Ich würde mit Hashes arbeiten. Ob das schneller ist wie der binäre Vergleich, müsste man ausprobieren.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 01.10.08 11:36
es ist für ein synchronisationstool
und ne kopie is langsamer als ein vergleich oder?
wenn datum und größe unterschiedlich sind, dann ist die datei schonmal verschieden
wenn sie gleich sind, könnte trotzdem der inhalt unterschiedlich sein
bei hashes ist das problem: es muss trotzdem die ganze datei eingelesen und dann nicht nur verglichen sondern auch noch gegeneinander gerechnet werden
also:
Vergleich:
1)Lade dateien in speicher
2) while(nicht ende) do PCardinal(speicher1)^=PCardinal(speicher2)^-->Wenn nicht dann Resuklt=false
das würde also schon abbrechen wenn das erste byte unterschiedlich ist
bei hash:
1)Lade dateien in speicher
2) Quelltext 1: 2: 3: 4: 5:
| var x:=0; while(nicht ende) do x:=x xor (PCardinal(speicher1)^); var x2:=0; while(nicht ende2) do x2:=x2 xor (PCardinal(speicher2)^); x=x2-->Wenn nicht dann Result=false |
Das wäre zumindest mein Verständnis davon
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 01.10.08 11:52
Dass bei Hashes die ganze Datei gelesen werden muss ist richtig. aber da muss nichts "gegengerechnet" werden. Die Hashes müssen nur verglichen werden.
Flamefire hat folgendes geschrieben : | wenn datum und größe unterschiedlich sind, dann ist die datei schonmal verschieden
wenn sie gleich sind, könnte trotzdem der inhalt unterschiedlich sein |
Richtig und deshalb sind diese Eigenschaften einer Datei unsicher.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 01.10.08 12:19
mit gegengerechnet meine ich die verknüpfung und "komprimierung" einer datei auf einen hash
da müssen ja einige vergleiche und xor verknüpfungen ausgeführt werden, die meiner meinung nach zahlenmäßig mehr und langsamer sind als ein direkter vergleich
bsp:
Datei1: 12345678
Datei2: 12345678
Vergleich:
1=1
2=2
3=3
...
Sind je 3 Vergleiche je Datensatz (4 Bytes vermutlich). 2mal länge des streams-(streamende?) und dann der direkte vergleich
Hash:
1 xor 2
xor 3
xor 4
Sind je Datei 1 Vergleich und eine Operation-->insgesammt 2 Vergeliche und 2 Operationen/Zuweisungen-->mehr als Vergleich
und ne Zuweisung ist doch langsamer als ein Vergleich
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 01.10.08 12:21
Hallo,
beide Dateien parallel einlesen ist nur dann schnell, wenn sie nicht auf der selben physikalischen Festplatte sind.
8k-Blöcke (obwohl, machen die meisten Festplatten nicht einen read ahead von 64 KB) einlesen geht Methode TStream.ReadBuffer, 2x 4k ist wohl besser für den first level Cache, aber egal die Festplatten sind eh zu langsam.
Alternativ, solange die Datei in den Hauptspeicher passt, diese komplett einlesen, möglicherweise ist die Sicherungsdatei weniger fragmentiert, da nicht mit ihr gearbeitet wird.
Die Originaldatei dann immer scheibchenweise einlesen und vergleichen.
Gruß Horst
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 01.10.08 12:37
uff...
Bahnhof?
wie mache ich das jz?
Delphi-Quelltext 1: 2:
| f1:=TFileStream.Create(sFile,...); f1.read(???); |
Und ja meist sind sie nicht auf der selben festplatte-->Backupfestplatte auf USB o.ä.
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 01.10.08 15:28
Hallo,
wie keine Hilfe bei Delphi dabei...
Hatte ich mal an einen String übergeben....
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:
| const BufSize = 4096; var fs : TFileStream; FileContent: string; i,gelesen : integer; begin i := fs.size; SetLength(Filecontent, BufSize); with fs do begin while (position-size) <0 do begin gelesen := Read(FileConten[1],BufSize); If gelesen< Bufsize then begin SetLength(Filecontent, gelesen); Auswerten; break; end; Auswerten; end; |
Gruß Horst
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Do 02.10.08 12:14
ok gut danke
werds mal auf performance testen...mal gucken was rauskommt
|
|