9 Gäste und 0 Benutzer online | Anmelden | Registrieren
Startseite Windows-Artikel Problemlösungen Einstellungen Anleitungen Hardware FAQ C#.NET Forum Gästebuch Programme Onlinetools Downloads Suche Links Impressum Kontakt Anmelden |
Zu den C#.NET-Artikeln Verzeichnis rekursiv durchsuchen - C# Am 16.10.2007 verfasst von Andreas Nägeli. Hits: 2896 Das Durchsuchen von Ordnerstrukturen wird immer wieder benötigt. Dieser Artikel soll Ihnen eine Methode zum rekursiven Suchen nach einer Datei in einem angegebenen Verzeichnis (plus Unterverzeichnisse) erklären. Dabei soll die gesamte Suche in eine extra Klasse ausgelagert werden, für die die folgenden Referenzen benötigt werden:
Beginnen wir zunächst mit ein paar Delegates, die wir im späteren Verlauf benötigen werden. Ein Delegate ist ein Zeiger auf eine Funktion mit einer bestimmten Signatur. Wir werden diese Zeiger später benötigen, um Nachrichten an das Objekt zu senden, dass unsere Suchfunktion aufgerufen hat. Die Definitionen von Delegates finden außerhalb von Klassen statt:
Wie aus den Namen ersichtlich wird, werden wir diese Funktionen verwenden, wenn eine passende Datei gefunden oder der Suchvorgang abgeschlossen wurde, wenn ein Zugriffsfehler auftritt oder wenn sich die Anzahl an durchsuchten Ordnern geändert hat. Außerdem wird die letzte Methode dazu benutzt werden, den aktuell bearbeiteten Ordner anzuzeigen. Selbstverständlich könnte man auch alle Statusobjekte an das Suchobjekt übergeben. Allerdings hätte dies den Nachteil, dass in der Suchlasse selbst bestimmt werden müsste, was in die Steuerelemente eingetragen wird. Auf die hier angewandte Weise bleibt mehr Spielraum für die aufrufende Klasse, die das Suchobjekt verwenden möchte. Kommen wir nun zur eigentlichen Klasse CLRecursiveSearch:
Zunächst definieren wir 5 öffentliche Delegaten, die später verwendet werden können, um Methoden für Rückmeldungen aufzurufen. Die Variable thread wird später den Thread beinhalten, in dem wir die rekursive Suche an sich ausführen werden. current enthält das Verzeichnis, das gerade durchsucht wird, searchfor den Namen der Datei, die wir suchen. Die Integervariablen folders und files merken sich, wie viele Ordner bzw. Dateien wir bereits gefunden haben. Der Wert -1 deutet an, dass noch keine Suche stattgefunden hat. Zuletzt die Variable level. Sie merkt sich die Rekursionsebene auf der wir uns befinden. Dies wird später nötig sein um herauszufinden, wann wir am Ende der Suche angelangt sind. Die öffentlichen getMethoden können von der ausführenden Klasse verwendet werden, um die entsprechenden Variablen auszulesen. Um später nach einer Datei zu suchen, werden wir die Methode Search aufrufen. Diese ist wie folgt definiert:
Zunächst prüfen wird, ob der zu suchende Dateiname nicht leer ist und ob das Suchverzeichnis existiert. Wenn hier ein Fehler auftritt, werfen wir eine entsprechende Exception. Danach setzen wir die Parameter für die Suche. folders wird hier auf 1 gesetzt, da das Ausgangsverzeichnis ebenfalls mitgezählt werden muss. Mit einem neuen Thread, der die Run-Methode ausführt, starten wir die Suche.
Mit jedem Durchlauf der Run-Methode gehen wir eine Stufe tiefer in die Ordnerstruktur. Deshalb inkrementieren wir hier zunächst den Zähler für die Rekursionsebene. Da sich der Ordner mit dem Aufruf der Funktion geändert hat, lösen wir die Funktion aus, die in delegateFolderChanged hinterlegt wurde. Danach ermitteln wir mit der DirectoryInfo-Klasse alle Dateien und Unterverzeichnisse in diesem Ordner. Mit diesen Daten erhöhen wir die Anzahl an Dateien und gefundenen Verzeichnissen entsprechend. Nun gehen wir alle Dateien einzeln durch und prüfen, ob sich eine mit dem gesuchten Dateinamen in diesem Verzeichnis befindet. Wenn ja, lösen wir die entsprechende Funktion hinter delegateFileFound aus. Nun setzen wir für jeden Unterordner in diesem Verzeichnis zunächst die current Variable und rufen dann erneut die Run-Methode auf. Dies ist der eigentliche Rekursionsschritt. Unsere Methode wird nun auch jeden einzelnen Unterordner durchsuchen, und sich selbst wiederum mit dessen Unterordnern aufrufen und so weiter - bis es irgendwann keine Unterordner mehr gibt und die Rekursionsebene wieder veringert wird. Haben wir nicht die Rechte, um auf einen bestimmten Ordner zuzugreifen, so wird der catch-Block ausgeführt, in dem wiederum eine Delegate-Funktion ausgeführt wird. Abschließend müssen wir nur noch die Variable für die Rekursionsebene dekrementieren. Haben wir am Ende dieser Funktion wieder die 0te Rekursionsstufe erreicht, so wissen wir, dass die Rekursion zu Ende ist. Dementsprechend können wir hier die passende Funktion aufrufen, die im Delegate hinterlegt wurde. Da rekursive Algorithmen nicht einfach zu verstehen sind, möchte ich den Vorgang nochmals an einem Beispiel demonstrieren: ![]() Angenommen, wir füttern die Suche mit "C:" als Startverzeichnis für die rekursive Suche. Der Algorithmus listet dann zunächst alle Dateien in "C:" auf und wird nun für jedes Unterverzeichnis nochmals Run aufrufen. Als erster Unterordner ist "Programme" an der Reihe. Sobald die Run-Methode mit current=C:\Programme aufgerufen wurde, wird der Ordner durchsucht und wieder wird mit der Abarbeitung der Unterverzeichnisse begonnen. Sind wir bei "C:\Programme\Programm I\Ordner I" angelangt ist es nicht mehr möglich, eine Stufe tiefer zu gehen. Das heißt, die foreach-Schleife mit den Unterordnern hat 0 Durchläufe und die Funktion beendet sich zum ersten mal regulär und springt eine Stufe nach oben. Als nächstes wird dann der zweite Ordner in der Liste, "Ordner II" durchsucht. Da auch hier nichts zu finden ist springen wir wieder eine Stufe höher, bemerken, dass wir in "Programm I" bereits alles erledigt haben und springen noch eine Stufe höher. Auch in "Programme" gibt es nichts mehr zu tun, so dass nun die Liste mit dem Windowsordner weitergeführt wird. Die Parameter der Suche würden sich wie folgt auflisten lassen: ![]() Was bleibt, ist nur noch die ausführende Klasse richtig zu implementieren. Dazu müssen wir nur die Delegates belegen und die Search-Methode ausführen:
Die einzelnen Funktionen, die wir hier verwenden, müssen dann selbstverständlich noch angegegeben werden.
Dieser Teil erklärt sich allerdings am besten aus dem Beispielprojekt selbst. Den Algorithmus, den wir hier analysiert haben, können Sie auch für andere Zwecke verwenden, z.B. zum Indizieren von Verzeichnissen oder Ähnlichem. Kommentiertes Codebeispiel herunterladen (CLRecursiveSearch.rar, 38 KB, VC80) Bewertung dieses Artikels von 18 Benutzern: - 9.28 / 10 Punkte |
|
|||||||
2002 - 2008 Computerleben.net Sitemap |