Autor Beitrag
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: 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. :lol: Das hat Assarbad eigenmächtig gemacht. Die Stelle war in Wirklichkeit von Anfang an frei. :mrgreen:

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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 447
Erhaltene Danke: 2

W2K, XP, Vista64, Win7 64
RAD-Studio 2010
BeitragVerfasst: Mi 03.09.08 13:43 
user profile iconene 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: 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. :mrgreen:
Einloggen, um Attachments anzusehen!
ene Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: 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



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

ausblenden 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
    {
        // Versuche die Datei zu Öffnen
        using (FileStream fs = new FileStream(filePath, FileMode.Open))
        {
            //We can check whether the file can be read or written by using fs.CanRead or fs.CanWrite here.
            // Wir können mit der Methode fs.CanRad / fs.CanWrite hier überprüfen ob die Datei gelesen/geschrieben werden kann.
        }
        return false;
    }
    catch (IOException ex)
    {
        // Prüfen ob die Nachricht eine io.file Meldung ist.
        string message = ex.Message.ToString();
        // Check if the file is in use
        // Prüfe ob die Datei in benutzung oder gesperrt ist und gib Wahr zurück oder gehe zurück.
        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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 306
Erhaltene Danke: 14



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