Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  if (FindFirst(source,faAnyFile,F1)=0and (FindFirst(target,faAnyFile,F2)=0then
  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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6388
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: 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



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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)
ausblenden 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



BeitragVerfasst: 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.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1653
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 01.10.08 12:37 
uff...
Bahnhof?

wie mache ich das jz?
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1653
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 01.10.08 15:28 
Hallo,

wie keine Hilfe bei Delphi dabei...
Hatte ich mal an einen String übergeben....
ausblenden 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// Ist in Delphi immer Nullterminiert 
    i,gelesen : integer; 
begin  
  i :=  fs.size; 
  SetLength(Filecontent, BufSize); //Nur bei ausreichend Platz 
  
  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;
  // Du übwergibst nun pChar(FileContent), die #0 steht automatisch am Ende


Gruß Horst
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 02.10.08 12:14 
ok gut danke
werds mal auf performance testen...mal gucken was rauskommt