Hiermal eine elegante Implementation einer rekursiven Datei- und Ordner-Suche:
Aufruf-Beispiel (Form mit 2 Listboxen):
Erläuterungen
Update, Erweiterung
Habe die Geschichte nunmehr in 3 verschiedenen Views implementiert
Wichtiger Hinweis
Die Solution muß zunächst mal kompiliert werden (Menü - Erstellen), bevor man das MainForm im Designer angugge kann. Denn auf dem MainForm sind UserControls plaziert, und der Form-Designer kann die nur anzeigen, wenn sie als dll vorliegen.
Nachtrag 11-2014
Hier eine geschwindigkeits-optimierte Variante (ca. 3 * schneller) von @simpleSoft - vielen Dank!
VB.NET-Quellcode
- Private Sub CollectFilesAndFolders(ByVal rootDirs As IEnumerable(Of DirectoryInfo), _
- ByVal folderCollector As ICollection(Of DirectoryInfo), _
- ByVal fileCollector As ICollection(Of FileInfo), _
- Optional ByVal pattern As String = "*.*")
- 'rekursive anonyme Methode
- Dim recurse As Action(Of IEnumerable(Of DirectoryInfo)) = _
- Sub(dirs As IEnumerable(Of DirectoryInfo))
- For Each dirinf In dirs
- Dim files As IEnumerable(Of FileInfo)
- Try
- files = dirinf.EnumerateFiles(pattern)
- Catch ex As UnauthorizedAccessException
- 'für manche Directories hat das Prog keine Rechte
- Continue For
- End Try
- For Each fileInf In files
- fileCollector.Add(fileInf)
- Next
- folderCollector.Add(dirinf)
- 'selbst-aufruf
- recurse(dirinf.EnumerateDirectories)
- Next
- End Sub
- 'anonyme Methode aufrufen
- recurse(rootDirs)
- End Sub
Aufruf-Beispiel (Form mit 2 Listboxen):
VB.NET-Quellcode
- Private Sub GetFilesAndFolders(ByVal rootPath As String)
- Dim folders As New List(Of DirectoryInfo)
- Dim files As New List(Of FileInfo)
- Dim rootDirs = {New DirectoryInfo(rootPath)} 'rootDirs enthält hier nur 1 Directory
- CollectFilesAndFolders(rootDirs, folders, files, txtPattern.Text)
- 'Collect-Ergebnisse verwenden
- lstDirectories.DataSource = folders
- lstFiles.DataSource = files
- End Sub
Erläuterungen
- die Methode CollectFilesAndFolders() nimmt als root nicht nur ein DirectoryInfo, sondern gleich viele - kann also mehrere unzusammenhängende Ordner in einem Aufwasch durchsuchen. Will man nur einen Ordner durchsuchen, gibt man ihr halt eine Auflistung mit nur einem DirectoryInfo - etwa ein Array zu deklarieren erfordert ja nur 2 zusätzliche Zeichen {}:Das ist nur minimal aufwändiger, hält aber o.g. Option offen.
- Die Methode legt sich nicht auf bestimmte Auflistungen fest, sondern arbeitet auf den allgemeinst-möglichen Interfaces (IEnumerable(Of T), ICollection(Of T)). Dadurch kann man ihr als rootDirs Arrays, Lists, BindingLists, Queues, Stacks - egal was geben - es muß nur IEnumerable(Of DirectoryInfo) implementieren
Auch die Collectoren sind flexibel - es müssen nur Auflistungen sein, die über eine .Add-Methode verfügen - ICollections eben.
- 2010 - spezifisch ist die anonyme rekursive Methode, die in
CollectFilesAndFolders()
eingebaut ist.
Vorteil dieser Technologie ist, dass die rekursive Methode Zugriff auf die lokalen Variablen der Umgebung hat, sodaß folderCollector und fileCollector ohne jeden Umstand befüllt werden können, ebenso wie auch der pattern zugreifbar ist - egal, in welcher Verschachtelungstiefe die Rekursion grade läuft.
Wer schonmal eine Rekursion programmiert hat, kennt die Umständlichkeit, dass man entweder extra-Klassenvariablen einführen muß - und damit gegen das Kapselungs-Prinzip verstößt - oder man muß den Selbst-Aufruf sehr umständlich gestalten, nämlich folderCollector, fileCollector und pattern jedesmal als Parameter reinreichen, damit sie in der Rekursion verfügbar sind.
Bei einer rekursiven anonymen Methode sind 2 Dinge zu beachten- Option Infer failt, also die Signatur muß explizit deklariert sein (hier:
Action(Of IEnumerable(Of DirectoryInfo))
).
Ansonsten meckert der Compiler, wenn die anonyme Methode sich selbst aufrufen will. - Erst die rekursive anonyme Methode ausprogrammieren, danach(!) kann man sie auch aufrufen
- Option Infer failt, also die Signatur muß explizit deklariert sein (hier:
Update, Erweiterung
Habe die Geschichte nunmehr in 3 verschiedenen Views implementiert
- per DatagridView und EinzelblattView, mit einer ObjectBindingSource
- Mit Listboxen sowohl für Directories als auch Files
- mit Treeview mit Checkboxen für Directories
Wichtiger Hinweis
Die Solution muß zunächst mal kompiliert werden (Menü - Erstellen), bevor man das MainForm im Designer angugge kann. Denn auf dem MainForm sind UserControls plaziert, und der Form-Designer kann die nur anzeigen, wenn sie als dll vorliegen.
Nachtrag 11-2014
Hier eine geschwindigkeits-optimierte Variante (ca. 3 * schneller) von @simpleSoft - vielen Dank!
Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von „ErfinderDesRades“ ()