Autor |
Beitrag |
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Mi 03.09.08 07:35
Moin,
Da ich mit den ganzen Dublettenfindern nicht so recht zufrieden bin, möchte ich gerne einen für meine Ansprüche schreiben. Als erstes gehts mir aber um die Strategie dabei. Hier habe ich mir 2 Möglichkeiten überlegt:
1. Alle Ordner durchsuchen (rekursiv) und dabei alle gefundenen Dateien in ein Array oder ein Listview schieben. Und dann sequentiell vergleichen.
2. Alle Daten in eine DB schreiben und den Vergleich mittels SQL erstellen.
Vorteil von 1. ist, dass ich keine DB brauche, allerdings dürfte dass relativ Speicherintensiv werden und vom Gefühl her auch langsamer als mit SQL. Bei 2. ist das schreiben der Daten bestimmt etwas langsamer, dafür dürfte die Auswertung schneller gehen und die sehe ich als kritischer an.
Hat jemand damit schon Erfahrungen oder gibt es noch andere Möglichkeiten? Bin für jede Antwort dankbar! 
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 03.09.08 08:49
Für jede Datei einen Hash (z.B. CRC, MD5 o.ä) erstellen. Die Liste nach diesem Hash sortieren. Benachbarte Einträge der Liste mit gleichem Hash näher untersuchen (um Kollisionen d.h. identischer Hash trotz unterschiedlichem Inhalt auszuschließen). Aufwand O(n log n) für das Sortieren. Danach linear.
Alternativ eine Hashmap verwenden, diese bei einer Kollision modifizieren. Aufwand: O(1)
_________________ Na denn, dann. Bis dann, denn.
|
|
ene 
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Mi 03.09.08 08:52
Auch ne Möglichkeit. Werd mal schauen, wie weit mich das bringt.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Mi 03.09.08 13:37
Guck mal hier :
www.delphipraxis.net...lekiller&start=0
Das kam zwar nie richtig zum Abschluss, aber da lässt sich eine Menge brauchbarer Source und Denkanstöße finden. Als Nebenprodukt dieser Aktivitäten bin ich jetzt sogar Administrator des Projektes bei SourceForge.  Das hat Assarbad eigenmächtig gemacht. Die Stelle war in Wirklichkeit von Anfang an frei.
P.S.: richtig interessant wird es ab Beitrag #64
_________________ Gruß
Hansa
Zuletzt bearbeitet von hansa am Mi 03.09.08 13:43, insgesamt 1-mal bearbeitet
|
|
delphi10
      
Beiträge: 447
Erhaltene Danke: 2
W2K, XP, Vista64, Win7 64
RAD-Studio 2010
|
Verfasst: Mi 03.09.08 13:43
ene hat folgendes geschrieben: | Auch ne Möglichkeit. Werd mal schauen, wie weit mich das bringt. |
IMHO nicht auch ne Möglichkeit, sondern es geht nur so. Doubletten kann man nicht am Filenamen erkennen, sondern nur am identischen Inhalt. Der Dateiname sollte keine Rolle spielen. Zwei inhaltlich identische Dateien mit unterschiedlichen Namen würde man nicht als Doublette erkennen, zwei inhaltlich verschiedene mit gleichen Namen aber als Doublette einordnen.
Das ist jetzt mal so eben logisch in die Ecke gedacht, vielleicht gibt es ja noch mehr Möglichkeiten.
cu delphi10
_________________ Salus populi suprema lex esto
|
|
ene 
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Mi 03.09.08 13:44
Uff da werd ich mir die 10 Seiten mal bei Gelegenheit zu gemüte führen.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
Chryzler
      
Beiträge: 1097
Erhaltene Danke: 2
|
Verfasst: Mi 03.09.08 15:41
Hab mal meine Version angehängt, die ich aus Spaß vor einiger Zeit in C# geschrieben habe. Er arbeitet in 2 Schritten: zuerst werden alle Dateigrößen gesammelt, im zweiten Schritt wird dann der MD5-Hash derjenigen Dateien gesammelt, die gleiche Dateigrößen haben. So müssen Dateien, die aufgrund ihrer Größe gar nicht doppelt vorhanden sein können, nicht auch noch gehasht werden. Denkbar wäre noch ein dritter Schritt, der Dateien mit dem selben Hash Byte für Byte vergleicht, hab ich aber letzen Endes nicht implementiert.
EDIT: Äh der Sourcecode war nur für mich gedacht, wenn ihn also jemand versteht würds mich wundern. 
Einloggen, um Attachments anzusehen!
|
|
ene 
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Mi 03.09.08 15:44
Ok Ok, ich werde mir das alles reintun. Also rechnet mit einer Antwort zu Weihnachten  Ne im Ernst, bisher wars nur eine Idee und deswegen kanns mit der Umsetzung "etwas" dauern. Aber auf jeden Fall jetzt schon ein dickes Dankeschön!
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
troniac
Hält's aus hier
Beiträge: 1
|
Verfasst: Mo 10.12.12 18:11
Sorry wegen dem alttne Post, habe noch die Prüfung der File.Lock hinzugefügt. Könntet ihr dann auch tun um Ausnahmen abzufangen wenn die Datei gelockt ist.
Desweiteren habe ich noch eine Methode hinzugefügt die reagieren kann und die Datei als Schattenkopie öffnet, wenn ein Schalter --Shadow übergeben wird.
C#-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:
| static bool IsFileInUse(string filePath) { try { using (FileStream fs = new FileStream(filePath, FileMode.Open)) { } return false; } catch (IOException ex) { string message = ex.Message.ToString(); if (message.Contains("The process cannot access the file")) return true; else throw; } } |
Hier eine Funktion die, die Verzeichnisse Manuell durchläuft und Verzeichnisse überspringt die keinen Zugriff erlauben.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| public static IEnumerable<string> GetFiles(string root, string searchPattern) { Stack<string> pending = new Stack<string>(); pending.Push(root); while (pending.Count != 0) { var path = pending.Pop(); string[] next = null; try { next = Directory.GetFiles(path, searchPattern); } catch { } if (next != null && next.Length != 0) foreach (var file in next) yield return file; try { next = Directory.GetDirectories(path); foreach (var subdir in next) pending.Push(subdir); } catch { } } } |
modifizierte Quelle
Source only (7z, 5.98 KB)
Einloggen, um Attachments anzusehen!
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: Di 11.12.12 03:17
Eine Prüfsumme für jede Datei zu erstellen, dauert viel zu lange. Wesentlich effizienter und schneller ist ein Binärvergleich, der beim Auftauchen eines Unterschieds den Vergleich sofort abbricht. Habe vor Jahren auch solch ein Programm geschrieben, übrigens optional auch mit Prüfsummenvergleich, den ich jedoch aus dem genannten Grund nie nutze. War ein mehrjähriges Projekt, das ich jedoch schon lange nicht mehr weiterentwickle. Heutzutage würde ich beim Vergleich noch wesentlich gezielter vorgehen, z.B. Vergleich vom Änderungsdatum und Dateityp in Kombination mit dem Binärvergleich. Natürlich können auch Dateien mit verschiedenem Änderungsdatum oder verschiedene Dateitypen den gleichen Inhalt haben (normalerweise jedoch aber wohl eher nicht).
|
|
|