Pouvez-vous appeler Répertoire.GetFiles() avec plusieurs filtres?
Je suis en train d'utiliser le Directory.GetFiles()
méthode pour récupérer une liste de fichiers de plusieurs types, tels que mp3
's et jpg
s'. J'ai essayé les deux suivantes avec pas de chance:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
Est-il un moyen de le faire dans un appel?
- Comme une note de côté , à l'aide de GetFiles modèle de recherche pour le filtrage de l'extension n'est pas sûr.Par exemple, vous avez deux fichiers Test1.xls et Test2.xlsx et vous souhaitez filtrer xls fichier à l'aide du modèle de recherche *.xls, mais GetFiles le retour à la fois Test1.xls et Test2.xlsx . Lire la Note de la Section pour plus d'info
- Alors, comment éviter cela?
- Comment est-ce pas sûre? Qui ressemble à une fonction et non un bug.
Vous devez vous connecter pour publier un commentaire.
Pour .NET 4.0 et versions ultérieures,
Pour les versions antérieures de .NET,
edit: lisez les commentaires. L'amélioration que Paul Farry suggère, et la mémoire/problème de performance que Chrétienne.K points sont à la fois très important.
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
avecDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx, ce qui permettra d'éviter les problèmes de mémoire que @Christian.K mentionne.s
danss => s.EndsWith(".mp3") || s.EndsWith(".jpg")
???s
représente chaque nom de fichier renvoyé par l'appel àDirectory.EnumerateFiles
/Directory.GetFiles
.Where(f => _validExtensions.Contains(Path.GetExtension(f).ToLower()))
. FondamentalementContains
est beaucoup plus rapide que de procéder à des comparaisons de chaîne plusieurs fois.Comment à ce sujet:
Je l'ai trouvé ici (dans les commentaires): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
Parallel.ForEach
de les obtenir en parallèleSi vous avez une grande liste des extensions de vérifier que vous pouvez utiliser. Je ne voulais pas créer beaucoup de OU déclarations j'ai donc modifié ce lette a écrit.
Path.GetExtension
revient".ext', pas '*.ext " (au moins en 3,5+)..abc
, et supportedExtensions contient.abcd
. Correspondent, bien qu'il ne le devrait pas. Pour corriger:supportedExtensions = ".jpg|.abcd|";
avec.Contains(Path.GetExtension(s).ToLower() + "|")
. C'est, inclure votre caractère de séparation dans le test. IMPORTANT: votre caractère séparateur doit également être après la DERNIÈRE entrée dans supportedExceptions.pour
Vous pouvez:
Directory.EnumerateFiles
pour un gain de performances (Quelle est la différence entre le Répertoire.EnumerateFiles vs Répertoire.GetFiles?).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
plutôt que.ToLower().EndsWith("aspx")
)Mais le vrai avantage de
EnumerateFiles
s'affiche lorsque vous fractionnez les filtres et fusionner les résultats:Cela devient un peu plus rapide si vous n'avez pas à les transformer en boules (c'est à dire
exts = new[] {"*.mp3", "*.jpg"}
déjà).L'évaluation de la Performance basée sur les points suivants LinqPad test (note:
Perf
ne fait que répéter le délégué 10000 fois)https://gist.github.com/zaus/7454021
( republié et s'étendait de "duplicata" depuis que la question est spécifiquement demandé aucune LINQ: Plusieurs fichiers extensions searchPattern pour le Système.IO.Répertoire.GetFiles )
.FilterFiles(path, "jpg", "gif")
) est mieux que "explicite globs" (c'est à dire.FilterFiles(path, "*.jpg", "*.gif")
).StringComparison.OrdinalIgnoreCase
signifie qu'il serait travailler pour.jpg
ou.Jpg
ou.JPG
, etc.json.html
) qui correspond à plus d'un glob.Je sais que c'est une vieille question, mais LINQ: (.NET40+)
file.ToLower()
facilement correspondre à haut-cas des extensions. Et pourquoi pas un extrait de l'extension de la première, donc la Regex n'a pas à examiner le chemin d'accès complet:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
Une autre façon d'utiliser Linq, mais sans avoir à retourner le tout et filtrer dans la mémoire.
C'est en fait 2 appels à
GetFiles()
, mais je pense que c'est cohérent avec l'esprit de la question et les retourne dans un énumérable.Il y a aussi une descente solution qui semble ne pas avoir de mémoire ou de surcharge de performance et d'être assez élégant:
Nope. Essayez ce qui suit:
Prises à partir de: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
Laisser
Puis
ou
Je ne peux pas utiliser
.Where
méthode parce que je suis à la programmation .NET Framework 2.0 (Linq est pris en charge uniquement dans .NET Framework 3.5+).Code ci-dessous n'est pas sensible à la casse (donc
.CaB
ou.cab
seront également cités).La fonction suivante recherches sur des modèles multiples, séparés par des virgules. Vous pouvez également spécifier une exclusion, par exemple: "!web.config" permet de rechercher les fichiers et de les exclure "du web.config". Les modèles peuvent être mélangés.
Utilisation:
file.Extension.ToLower()
est une mauvaise pratique.Viens de trouver une autre façon de le faire. Toujours pas d'une seule opération, mais le fait de lancer pour voir ce que les autres pensent d'elle.
Ce sujet
Faire des extensions que vous voulez une chaîne de je.e ".mp3.jpg.wma.wmf" et de vérifier ensuite si chaque fichier contient l'extension que vous voulez.
Cela fonctionne avec .net 2.0 car il ne permet pas l'utilisation de LINQ.
L'avantage de cette approche est que vous pouvez ajouter ou supprimer des extensions sans modifier le code, je l'ai.e pour ajouter des images png, il suffit d'écrire myExtensions=".jpg.mp3.png".
s
Nop... je crois que vous avez à faire autant d'appels que les types de fichiers que vous le souhaitez.
Je voudrais créer une fonction de moi-même en prenant une matrice de chaînes de caractères, avec les extensions dont j'ai besoin et puis itérer sur ce tableau de faire de tous les appels nécessaires. Cette fonction doit retourner une liste générique des fichiers correspondant aux extensions que j'avais envoyé.
Espère que cela aide.
dans .NET 2.0 (pas de Linq):
Puis l'utiliser:
J'ai eu le même problème et impossible de trouver la bonne solution j'ai donc écrit une fonction appelée GetFiles:
Cette fonction fera appel
Directory.Getfiles()
qu'une seule fois.Par exemple appeler la fonction comme ceci:
EDIT: Pour obtenir un fichier avec plusieurs extensions de l'utiliser:
Par exemple appeler la fonction comme ceci:
Je me demande pourquoi il y a autant de "solutions" posté?
Si mon rookie-compréhension sur la façon dont GetFiles travaux est de droite, il y a seulement deux options et l'une des solutions ci-dessus peut être réduit à ces:
GetFiles, puis filtre: Rapide, mais un mémoire killer en raison de stocker des frais généraux jusqu'à ce que les filtres sont appliqués
Filtre en GetFiles: plus Lent plus les filtres sont fixés, mais la faible utilisation de la mémoire comme aucun frais n'est stockée.
Ceci est expliqué dans l'un des postes ci-dessus avec un nombre impressionnant de référence: Chaque option de filtre provoque une salle de GetFile d'opération, de sorte que la même partie du disque est lu plusieurs fois.
À mon avis, l'Option 1) est mieux, mais à l'aide de la SearchOption.AllDirectories sur des dossiers comme C:\ serait d'utiliser d'énormes quantités de mémoire.
À cet effet, je voudrais simplement faire un appel récursif à la sous-méthode qui passe par tous les sous-dossiers à l'aide de l'option 1)
Ce qui devrait entraîner seulement 1 GetFiles-opération sur chaque dossier et à cet effet, être rapide (Option 1), mais utiliser seulement une petite quantité de mémoire que les filtres sont appliqués afters de chacun des sous-dossiers de la lecture -> frais généraux sont supprimés après chaque sous-dossier.
S'il vous plaît corrigez-moi si je me trompe. Je suis comme je l'ai dit tout à fait nouveau pour la programmation, mais veulent acquérir une compréhension plus profonde des choses, à terme, être bon à ce jeu 🙂
je ne sais pas quelle solution est la meilleure, mais j'utilise ceci:
Si vous utilisez VB.NET (ou importée de la dépendance dans votre projet C#), il existe une méthode pratique qui permet de filtrer les extensions multiples:
Dans VB.NET cela peut être accédé par le biais de la Mon-espace de noms:
Malheureusement, ces méthodes pratiques ne prennent pas en charge paresseusement évalué variante comme
Directory.EnumerateFiles()
n'.À l'aide de GetFiles modèle de recherche pour le filtrage de l'extension n'est pas sûr!!
Par exemple, vous avez deux fichiers Test1.xls et Test2.xlsx et vous souhaitez filtrer xls fichier à l'aide du modèle de recherche *.xls, mais GetFiles le retour à la fois Test1.xls et Test2.xlsx
Je n'étais pas conscient de cela et a reçu l'erreur en environnement de production lorsque certains fichiers temporaires soudainement été traités comme des fichiers. Modèle de recherche a été *.txt et les fichiers temporaires a été nommé *.txt20181028_100753898
Ainsi, la recherche de modèle ne peut pas être digne de confiance, vous devez ajouter un supplément de vérifier sur les noms de fichiers ainsi.
Ou vous pouvez simplement convertir la chaîne d'extensions Chaîne^
espère que cela aide quelqu'un:
Directory.GetFiles()
à l'aide de plusieurs extensions de fichier. Votre code est diriger une boîte de dialogue de fichier qui filtre ce qu'il affiche à l'utilisateur en fonction de multiples extensions. Ceux qui ne sont pas la même chose.