Benutzer mit den meisten Antworten
GetFiles mit Subdirectories liefert keine Werte

Frage
-
Hallo zusammen,
ich bin noch recht neu in .NET (war bsiher nur in VBA unterwegs) und bin grad ein wenig am rumtesten. Nun habe ich in meiner WPF-Applikation ein kleines Problem:
Ich habe dort eine Klasse, welche mir Dateien aus einem Pfad (=Laufwerk) zurückgeben soll. Dies funktioniert auch aber NUR mit "SearchTopLevelOnly", das ganze mit "SearchAllSubDirectories" funktioniert leider nicht -> bekomme nichts zurück. Kenn jemand zufällig das Problem bzw. eine Abhilfe ?
Vielen Dank.
Hier noch der Code, falls es weiter hilft (als pPath wird "E:\" übergeben:
Public Function getFiles(ByVal pPath As String) As Collection Dim colResult As New Collection For Each file In My.Computer.FileSystem.GetFiles(pPath, FileIO.SearchOption.SearchAllSubDirectories, "*.txt") colResult.Add(file) Next Return colResult End Function
Antworten
-
Hallo,
ich blende mich mal in eure Diskussion ein.
Das Problem einer rekursiven Dateisuche ist, das man nicht immer auf alle Verzeichnisse Zugriff hat. Auf das "System Volume Information" Verzeichnis, das die Wiederherstellungsinformationen des Betriebssystems enthält, hat unter normalen Umständen nicht einmal ein Administrator Zugriff.
Weder My.Computer.FileSystem.GetFiles - das sowieso überflüssiger als ein Kropf ist - noch System.IO.Directory.GetFiles fangen das ab, sondern reichen die UnAuthorizedAccessException weiter. Mit dem Endresultat, dass man kein Ergebnis bekommt.
In der MS KB gibt es einen Artikel SO WIRD'S GEMACHT: Rekursives Durchsuchen von Verzeichnissen in Visual Basic .NET, der eine alternative Lösung zeigt, aber IMHO es zuweit mit dem Schlucken von Ausnahmen treibt.
Eine alternative Variante, die nach mehreren Dateimustern suchen kann, das Ergebnis am Ende sortiert und die Rekursion durch einen Stack ersetzt:
Public Class FileHelper ''' <summary> ''' Erstellt eine Dateiliste rekursiv. ''' </summary> ''' <remarks> ''' Es kann nach mehreren Mustern gesucht werden, die durch ";" getrennt werden. ''' Dateien und Verzeichnisse auf die kein Zugriff besteht werden ausgelassen. ''' </remarks> ''' <param name="path">Der Ausgangspfad.</param> ''' <param name="searchPatterns">Eine Liste von Suchmustern</param> ''' <returns>eine List<String></returns> Public Shared Function FindFilesRecursive( _ ByVal path As String, _ ByVal searchPatterns As String) As List(Of String) If path Is Nothing Then Throw New ArgumentNullException("path") End If path = path.Trim() If path.Length = 0 Then Throw New ArgumentException("path") End If If String.IsNullOrEmpty(searchPatterns) Then Throw New ArgumentNullException("searchPatterns") End If ' Anfangspfad vorgeben (hier mögliche Ausnahme) path = System.IO.Path.GetFullPath(path) Dim fileList As New List(Of String) ' Trennen der Suchmuster Dim searchPatternList As New List(Of String) For Each pattern As String In searchPatterns.Split(";"c) pattern = pattern.Trim() If pattern.Length > 0 Then searchPatternList.Add(pattern) End If Next If searchPatternList.Count = 0 Then Return fileList End If Dim directoryStack As New Stack(Of String) directoryStack.Push(path) ' Verzeichnisse rekursiv (via Stack) durchlaufen Do While directoryStack.Count > 0 Dim directory As String = directoryStack.Pop() Try ' Durchlaufen aller Suchmuster For Each pattern As String In searchPatternList ' ... und zur Dateiliste hinzufügen fileList.AddRange(System.IO.Directory.GetFiles(directory, pattern)) Next Catch ex As UnauthorizedAccessException System.Diagnostics.Debug.WriteLine("No File Access " & directory) ' Kein Zugriff End Try ' Einfügen der Unterverzeichnisse in den Stack Try For Each subDirectory As String In System.IO.Directory.GetDirectories(directory) directoryStack.Push(subDirectory) Next Catch ex As UnauthorizedAccessException ' Kein Zugriff System.Diagnostics.Debug.WriteLine("No Directory Access " & directory) End Try Loop ' Sortiert die Dateinamen fileList.Sort(StringComparer.OrdinalIgnoreCase) Return fileList End Function ''' <summary> ''' Kleiner Test zu FindFilesRecursive ''' </summary> <Conditional("Debug")> _ Friend Shared Sub FindFileRecursiveTest() Dim path As String = "E:" 'Dim searchPatterns As String = "*.wav" Dim searchPatterns As String = "*.mp3;*.wav;*.wmv;*.wma" Dim fileList As List(Of String) = FileHelper.FindFilesRecursive(path, searchPatterns) Dim builder As New System.Text.StringBuilder(128) For Each name As String In fileList builder.AppendLine(name) Next System.IO.File.WriteAllText("F:\fileslist.txt", builder.ToString()) End Sub End Class
Gruß Elmar
- Als Antwort vorgeschlagen Elmar BoyeEditor Freitag, 14. August 2009 14:13
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 25. August 2009 19:24
- Bearbeitet Elmar BoyeEditor Sonntag, 24. November 2013 09:08 Format / Codeblock
Alle Antworten
-
das wars leider nicht.
Ich poste mal den ganzen Code rein, vielleicht stimmt der Aufruf nicht (was ich aber eig. nicht glaube):
Class Window1 Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded Dim colFound As New Collection Dim objData As New DataReader colFound = objData.getFiles("E:\") For Each foundFile As String In colFound MessageBox.Show(foundFile) Next End Sub End Class
Public Class DataReader Public Function getFiles(ByVal pPath As String) As Collection Dim colResult As New Collection For Each file As String In My.Computer.FileSystem.GetFiles(pPath, FileIO.SearchOption.SearchAllSubDirectories, "*.mp3") colResult.Add(file) Next Return colResult End Function End Class
-
Hallo,
wenn ich das richtig sehe hast Du einen Dateifilter für Mpeg-Files. Hast Du den Files von diesen Dateityp auf der E:\ - Partition? Wenn nicht würdest Du in eine nicht abgefangene Exception laufen und bekommst dann auch kein Ergebnis.
Ich werde Deinen Code gleich testen und melde mich wieder.
Schöne Grüße
Oliver -
Hab den Fehler wahrscheinlich gefunden:
Habe das ganze jetzt in ein try gepackt und bekomme folgendes:
Der Zugiff auf den Pad "E:\RECYCLER\hier steht ein file" wurde verweigert.
- Das heißt also, er durchläuft auch die versteckten- und Systemordner ? -
Problem ist nur: Mit For Each file As String In System.IO.Directory.GetFiles(pPath, "*mp3", IO.SearchOption.AllDirectories) bekomm ich den Fehler, dass er auf die "System Volume Information" nicht zugreifen kann.
Vielleicht find ich ja noch etwas, womit er nicht auf die ganzen versteckten Files und Ordner zugreifen will. -
Hallo,
das Grundgerüst dafür sieht so aus:
Try Dim dir As DirectoryInfo = New DirectoryInfo("E:\") Dim dirs As DirectoryInfo() = dir.GetDirectories() Dim di As DirectoryInfo For Each di In dirs di.GetFiles("*.mp3") Next Catch e As SecurityException End Try
Du mußt Deinen Code zur Verarbeitung der Informationen (z.B. Ausgabe in eine ListBox, etc) noch eingeben.
Schöne Grüße
Oliver -
Hallo,
das Grundgerüst dafür sieht so aus:
...
Schöne Grüße
Oliver
Das gibt leider auch wieder den Fehler, dass auf "System Volume Information" nicht zugegriffen werden kann
- Bearbeitet R.ST Sonntag, 9. August 2009 15:17
-
Hallo,
ich hab den Code gerade getestet. Mach bitte aus dem Catch e ein Catch ex. Das Programm kommt mit der Variable e nicht zu recht. Außerdem müßte es heissen Security.SecurityException oder Du schreibts eine Imports - Directive für System.Security. Das sollte das Problem mit dem Mülleimer usw. lösen.
Jetzt habe ich noch ein weiteres Problem gefunden. Wenn ein SubDirectory unter E:\ eigene SubDirectories hat, so werden diese im Programmdurchlauf ignoriert. Dateien die beispielsweise im Verzeichnis E:\music liegen werden aber fehlerfrei angezeigt, E:\music\film\ erscheint nicht in der Ausgabe.
Hier nocheinmal der Code:
Imports System.IO Imports System.Security Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Try Dim dir As DirectoryInfo = New DirectoryInfo("E:\") Dim dirs As DirectoryInfo() = dir.GetDirectories() Dim di As DirectoryInfo For Each di In dirs di.GetFiles("*.mp3") Dim fn As FileInfo Dim fname As String For Each fn In di.GetFiles("*.mp3") fname = fn.Name MessageBox.Show(fname) Next Next Catch ex As SecurityException End Try End Sub End Class
Schöne Grüße
Oliver
-
Hallo,
ich blende mich mal in eure Diskussion ein.
Das Problem einer rekursiven Dateisuche ist, das man nicht immer auf alle Verzeichnisse Zugriff hat. Auf das "System Volume Information" Verzeichnis, das die Wiederherstellungsinformationen des Betriebssystems enthält, hat unter normalen Umständen nicht einmal ein Administrator Zugriff.
Weder My.Computer.FileSystem.GetFiles - das sowieso überflüssiger als ein Kropf ist - noch System.IO.Directory.GetFiles fangen das ab, sondern reichen die UnAuthorizedAccessException weiter. Mit dem Endresultat, dass man kein Ergebnis bekommt.
In der MS KB gibt es einen Artikel SO WIRD'S GEMACHT: Rekursives Durchsuchen von Verzeichnissen in Visual Basic .NET, der eine alternative Lösung zeigt, aber IMHO es zuweit mit dem Schlucken von Ausnahmen treibt.
Eine alternative Variante, die nach mehreren Dateimustern suchen kann, das Ergebnis am Ende sortiert und die Rekursion durch einen Stack ersetzt:
Public Class FileHelper ''' <summary> ''' Erstellt eine Dateiliste rekursiv. ''' </summary> ''' <remarks> ''' Es kann nach mehreren Mustern gesucht werden, die durch ";" getrennt werden. ''' Dateien und Verzeichnisse auf die kein Zugriff besteht werden ausgelassen. ''' </remarks> ''' <param name="path">Der Ausgangspfad.</param> ''' <param name="searchPatterns">Eine Liste von Suchmustern</param> ''' <returns>eine List<String></returns> Public Shared Function FindFilesRecursive( _ ByVal path As String, _ ByVal searchPatterns As String) As List(Of String) If path Is Nothing Then Throw New ArgumentNullException("path") End If path = path.Trim() If path.Length = 0 Then Throw New ArgumentException("path") End If If String.IsNullOrEmpty(searchPatterns) Then Throw New ArgumentNullException("searchPatterns") End If ' Anfangspfad vorgeben (hier mögliche Ausnahme) path = System.IO.Path.GetFullPath(path) Dim fileList As New List(Of String) ' Trennen der Suchmuster Dim searchPatternList As New List(Of String) For Each pattern As String In searchPatterns.Split(";"c) pattern = pattern.Trim() If pattern.Length > 0 Then searchPatternList.Add(pattern) End If Next If searchPatternList.Count = 0 Then Return fileList End If Dim directoryStack As New Stack(Of String) directoryStack.Push(path) ' Verzeichnisse rekursiv (via Stack) durchlaufen Do While directoryStack.Count > 0 Dim directory As String = directoryStack.Pop() Try ' Durchlaufen aller Suchmuster For Each pattern As String In searchPatternList ' ... und zur Dateiliste hinzufügen fileList.AddRange(System.IO.Directory.GetFiles(directory, pattern)) Next Catch ex As UnauthorizedAccessException System.Diagnostics.Debug.WriteLine("No File Access " & directory) ' Kein Zugriff End Try ' Einfügen der Unterverzeichnisse in den Stack Try For Each subDirectory As String In System.IO.Directory.GetDirectories(directory) directoryStack.Push(subDirectory) Next Catch ex As UnauthorizedAccessException ' Kein Zugriff System.Diagnostics.Debug.WriteLine("No Directory Access " & directory) End Try Loop ' Sortiert die Dateinamen fileList.Sort(StringComparer.OrdinalIgnoreCase) Return fileList End Function ''' <summary> ''' Kleiner Test zu FindFilesRecursive ''' </summary> <Conditional("Debug")> _ Friend Shared Sub FindFileRecursiveTest() Dim path As String = "E:" 'Dim searchPatterns As String = "*.wav" Dim searchPatterns As String = "*.mp3;*.wav;*.wmv;*.wma" Dim fileList As List(Of String) = FileHelper.FindFilesRecursive(path, searchPatterns) Dim builder As New System.Text.StringBuilder(128) For Each name As String In fileList builder.AppendLine(name) Next System.IO.File.WriteAllText("F:\fileslist.txt", builder.ToString()) End Sub End Class
Gruß Elmar
- Als Antwort vorgeschlagen Elmar BoyeEditor Freitag, 14. August 2009 14:13
- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 25. August 2009 19:24
- Bearbeitet Elmar BoyeEditor Sonntag, 24. November 2013 09:08 Format / Codeblock