Ich versuche, die Directory.GetFiles()
Methode zu verwenden, um eine Liste von Dateien verschiedener Typen abzurufen, z. B. mp3
's und jpg
' s. Ich habe beide der folgenden ohne Glück versucht:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
Gibt es eine Möglichkeit, dies in einem Anruf zu tun?
c#
filesystems
.net
Jason Z.
quelle
quelle
Antworten:
Für .NET 4.0 und höher
Für frühere Versionen von .NET
bearbeiten: Bitte lesen Sie die Kommentare. Die von Paul Farry vorgeschlagene Verbesserung und das von Christian.K hervorgehobene Gedächtnis- / Leistungsproblem sind beide sehr wichtig.
quelle
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
mitDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx , die die Speicherprobleme zu vermeiden , dass @ Christian.K erwähnt.Wie wäre es damit:
Ich habe es hier gefunden (in den Kommentaren): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
quelle
Parallel.ForEach
, um sie parallel zu bekommenWenn Sie eine große Liste von zu überprüfenden Erweiterungen haben, können Sie Folgendes verwenden. Ich wollte nicht viele OR-Anweisungen erstellen, also habe ich geändert, was lette geschrieben hat.
quelle
Path.GetExtension
Gibt '.ext' zurück, nicht '* .ext' (zumindest in 3.5+)..abc
, und supportExtensions enthält.abcd
. Wird übereinstimmen, sollte es aber nicht. Zu beheben:supportedExtensions = ".jpg|.abcd|";
mit.Contains(Path.GetExtension(s).ToLower() + "|")
. Nehmen Sie also Ihr Trennzeichen in den Test auf. WICHTIG: Ihr Trennzeichen muss auch nach dem LETZTEN Eintrag in supportExceptions stehen.zum
Du könntest:
Directory.EnumerateFiles
für eine Leistungssteigerung ( Was ist der Unterschied zwischen Directory.EnumerateFiles und Directory.GetFiles? ).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
anstatt.ToLower().EndsWith("aspx")
)Der eigentliche Vorteil von
EnumerateFiles
zeigt sich jedoch, wenn Sie die Filter aufteilen und die Ergebnisse zusammenführen:Es wird ein bisschen schneller, wenn Sie sie nicht in Globs verwandeln müssen (dh
exts = new[] {"*.mp3", "*.jpg"}
bereits).Leistungsbewertung basierend auf dem folgenden LinqPad-Test (Hinweis:
Perf
Wiederholen Sie den Delegaten nur 10000 Mal) https://gist.github.com/zaus/7454021(neu gepostet und von 'duplicate' erweitert, da für diese Frage ausdrücklich kein LINQ angefordert wurde: Mehrere Dateierweiterungen searchPattern for System.IO.Directory.GetFiles )
quelle
.FilterFiles(path, "jpg", "gif")
) besser ist als "explizite Globs" (dh.FilterFiles(path, "*.jpg", "*.gif")
).Ich weiß, es ist eine alte Frage, aber LINQ: (.NET40 +)
quelle
file.ToLower()
einfache Verwendung von Erweiterungen in Großbuchstaben. Und warum nicht zuerst die Erweiterung extrahieren, damit Regex nicht den gesamten Pfad untersuchen muss:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
Es gibt auch eine Abstiegslösung, die keinen Speicher- oder Leistungsaufwand zu haben scheint und recht elegant ist:
quelle
Eine andere Möglichkeit, Linq zu verwenden, ohne jedoch alles zurückgeben und im Speicher filtern zu müssen.
Es sind eigentlich 2 Anrufe
GetFiles()
, aber ich denke, es stimmt mit dem Geist der Frage überein und gibt sie in einer Aufzählung zurück.quelle
Nee. Versuche Folgendes:
Entnommen aus: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
quelle
Lassen
Dann
oder
quelle
Ich kann nicht verwenden
.Where
Methode , da ich in .NET Framework 2.0 programmiere (Linq wird nur in .NET Framework 3.5+ unterstützt).Code ist unten nicht Groß- und Kleinschreibung (so
.CaB
oder.cab
wird auch aufgeführt werden).quelle
Die folgende Funktion sucht nach mehreren Mustern, die durch Kommas getrennt sind. Sie können auch einen Ausschluss angeben, z. B.: "! Web.config" sucht nach allen Dateien und schließt "web.config" aus. Muster können gemischt werden.
Verwendungszweck:
quelle
quelle
file.Extension.ToLower()
ist schlechte Praxis.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
in .NET 2.0 (kein Linq):
Dann benutze es:
quelle
quelle
Habe gerade einen anderen Weg gefunden, es zu tun. Immer noch nicht eine Operation, aber wirf sie raus, um zu sehen, was andere Leute darüber denken.
quelle
Wie wäre es mit
quelle
Machen Sie die gewünschten Erweiterungen zu einer Zeichenfolge, dh ".mp3.jpg.wma.wmf", und prüfen Sie dann, ob jede Datei die gewünschte Erweiterung enthält. Dies funktioniert mit .net 2.0, da LINQ nicht verwendet wird.
Der Vorteil dieses Ansatzes ist, dass Sie Erweiterungen hinzufügen oder entfernen können, ohne den Code zu bearbeiten, dh um PNG-Bilder hinzuzufügen, schreiben Sie einfach myExtensions = ". Jpg.mp3.png".
quelle
s
quelle
Nein ... Ich glaube, Sie müssen so viele Anrufe tätigen, wie Sie möchten.
Ich würde selbst eine Funktion erstellen, die ein Array für Zeichenfolgen mit den von mir benötigten Erweiterungen verwendet und dann auf diesem Array iteriert und alle erforderlichen Aufrufe ausführt. Diese Funktion würde eine allgemeine Liste der Dateien zurückgeben, die den von mir gesendeten Erweiterungen entsprechen.
Ich hoffe es hilft.
quelle
Ich hatte das gleiche Problem und konnte nicht die richtige Lösung finden. Deshalb schrieb ich eine Funktion namens GetFiles:
Diese Funktion ruft
Directory.Getfiles()
nur einmal auf.Rufen Sie zum Beispiel die Funktion folgendermaßen auf:
BEARBEITEN: Um eine Datei mit mehreren Erweiterungen zu erhalten, verwenden Sie diese:
Rufen Sie zum Beispiel die Funktion folgendermaßen auf:
quelle
Ich frage mich, warum es so viele "Lösungen" gibt?
Wenn mein Anfängerverständnis darüber, wie GetFiles funktioniert, richtig ist, gibt es nur zwei Optionen, und jede der oben genannten Lösungen kann auf diese zurückgeführt werden:
GetFiles, dann Filter: Schnell, aber ein Speicherkiller aufgrund des Speicheraufwands, bis die Filter angewendet werden
Filtern während GetFiles: Langsamer, je mehr Filter eingestellt sind, aber geringer Speicherbedarf, da kein Overhead gespeichert wird.
Dies wird in einem der oben genannten Beiträge mit einem beeindruckenden Benchmark erläutert: Jede Filteroption bewirkt eine separate GetFile-Operation, sodass derselbe Teil der Festplatte mehrmals gelesen wird.
Meiner Meinung nach ist Option 1) besser, aber die Verwendung von SearchOption.AllDirectories in Ordnern wie C: \ würde sehr viel Speicher verbrauchen.
Daher würde ich nur eine rekursive Untermethode erstellen, die mit Option 1) alle Unterordner durchläuft.
Dies sollte nur 1 GetFiles-Operation für jeden Ordner verursachen und daher schnell sein (Option 1), aber nur wenig Speicher verwenden, da die Filter nach dem Lesen jedes Unterordners angewendet werden -> Overhead wird nach jedem Unterordner gelöscht.
Bitte korrigieren Sie mich, wenn ich falsch liege. Ich bin, wie gesagt, ziemlich neu in der Programmierung, möchte aber ein tieferes Verständnis der Dinge erlangen, um irgendwann gut darin zu werden :)
quelle
Wenn Sie VB.NET verwenden (oder die Abhängigkeit in Ihr C # -Projekt importieren), gibt es tatsächlich eine praktische Methode, mit der Sie nach mehreren Erweiterungen filtern können:
In VB.NET kann über den My-Namespace darauf zugegriffen werden:
Leider unterstützen diese Convenience-Methoden keine träge bewertete Variante wie
Directory.EnumerateFiles()
diese.quelle
Ich weiß nicht, welche Lösung besser ist, aber ich benutze diese:
quelle
Hier finden Sie eine einfache und elegante Möglichkeit, gefilterte Dateien abzurufen
quelle
Oder Sie können einfach die Zeichenfolge der Erweiterungen in Zeichenfolge ^ konvertieren
quelle
Die Verwendung des GetFiles-Suchmusters zum Filtern der Erweiterung ist nicht sicher !! Zum Beispiel haben Sie zwei Dateien Test1.xls und Test2.xlsx und möchten die xls-Datei mithilfe des Suchmusters * .xls herausfiltern, aber GetFiles gibt sowohl Test1.xls als auch Test2.xlsx zurück. Ich war mir dessen nicht bewusst und habe einen Fehler in der Produktion erhalten Umgebung, in der einige temporäre Dateien plötzlich als richtige Dateien behandelt wurden. Das Suchmuster war * .txt und die temporären Dateien wurden * .txt20181028_100753898 benannt. Damit das Suchmuster nicht vertrauenswürdig ist, müssen Sie auch die Dateinamen zusätzlich überprüfen.
quelle