Comment filtrer Directory.EnumerateFiles avec plusieurs critères?

J’ai le code suivant:

List result = new List(); foreach (ssortingng file in Directory.EnumerateFiles(path,"*.*", SearchOption.AllDirectories) .Where(s => s.EndsWith(".mp3") || s.EndsWith(".wma"))) { result.Add(file); } 

Cela fonctionne bien et fait ce dont j’ai besoin. Sauf pour une petite chose. Je voudrais trouver un meilleur moyen de filtrer sur plusieurs extensions. Je voudrais utiliser un tableau de chaînes avec des filtres tels que celui-ci:

 ssortingng[] extensions = { "*.mp3", "*.wma", "*.mp4", "*.wav" }; 

Quelle est la manière la plus efficace de le faire en utilisant NET Framework 4.0 / LINQ? Aucune suggestion?

J’apprécierais toute aide étant un programmeur occasionnel 🙂

J’ai créé des méthodes d’assistance pour résoudre ce problème dont j’ai parlé plus tôt cette année.

Une version prend un modèle regex \.mp3|\.mp4 et l’autre une liste de chaînes et s’exécute en parallèle.

 public static class MyDirectory { // Regex version public static IEnumerable GetFiles(ssortingng path, ssortingng searchPatternExpression = "", SearchOption searchOption = SearchOption.TopDirectoryOnly) { Regex reSearchPattern = new Regex(searchPatternExpression, RegexOptions.IgnoreCase); return Directory.EnumerateFiles(path, "*", searchOption) .Where(file => reSearchPattern.IsMatch(Path.GetExtension(file))); } // Takes same patterns, and executes in parallel public static IEnumerable GetFiles(ssortingng path, ssortingng[] searchPatterns, SearchOption searchOption = SearchOption.TopDirectoryOnly) { return searchPatterns.AsParallel() .SelectMany(searchPattern => Directory.EnumerateFiles(path, searchPattern, searchOption)); } } 

Dépouillé du contexte LINQ, cela revient à savoir si un fichier correspond à une liste d’extensions. System.IO.Path.GetExtension() est un meilleur choix que Ssortingng.EndsWith() . Le multiple || peut être remplacé par .Contains() ou .IndexOf() selon la collection.

 var extensions = new HashSet(SsortingngComparer.OrdinalIgnoreCase) { ".mp3", ".wma", ".mp4", ".wav" }; ... s => extensions.Contains(Path.GetExtension(s)) 
 ssortingng path = "C:\\"; var result = new List(); ssortingng[] extensions = { ".mp3", ".wma", ".mp4", ".wav" }; foreach (ssortingng file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories) .Where(s => extensions.Any(ext => ext == Path.GetExtension(s)))) { result.Add(file); Console.WriteLine(file); } 

Comme je l’ai noté dans un commentaire, alors que les méthodes d’assistance de Mikael Svenson sont d’excellentes petites solutions, si vous essayez de faire quelque chose rapidement pour un projet unique, considérez l’extension Linq .Union () . Cela vous permet de réunir deux séquences énumérables. Dans votre cas, le code ressemblerait à ceci:

 List result = Directory.EnumerateFiles(path,"*.mp3", SearchOption.AllDirectories) .Union(Directory.EnumerateFiles(path, ".wma", SearchOption.AllDirectories)).ToList(); 

Cela crée et remplit votre liste de résultats sur une seule ligne.

L’approche la plus élégante est probablement:

 var directory = new DirectoryInfo(path); var masks = new[] { "*.mp3", "*.wav" }; var files = masks.SelectMany(directory.EnumerateFiles); 

Mais ce n’est peut-être pas le plus efficace.

Je sais que c’est un ancien message, mais j’ai trouvé une solution que les gens aimeraient utiliser.

 private IEnumerable FindFiles() { DirectoryInfo sourceDirectory = new DirectoryInfo(@"C:\temp\mydirectory"); ssortingng foldersFilter = "*bin*,*obj*"; ssortingng fileTypesFilter = "*.mp3,*.wma,*.mp4,*.wav"; // filter by folder name and extension IEnumerable directories = foldersFilter.Split(',').SelectMany(pattern => sourceDirectory.EnumerateDirectories(pattern, SearchOption.AllDirectories)); List files = new List(); files.AddRange(directories.SelectMany(dir => fileTypesFilter.Split(',').SelectMany(pattern => dir.EnumerateFiles(pattern, SearchOption.AllDirectories)))); // Pick up root files files.AddRange(fileTypesFilter.Split(',').SelectMany(pattern => sourceDirectory.EnumerateFiles(fileTypesFilter, SearchOption.TopDirectoryOnly))); // filter just by extension IEnumerable files2 = fileTypesFilter.Split(',').SelectMany(pattern => sourceDirectory.EnumerateFiles(pattern, SearchOption.AllDirectories)); } 

Pour le filtrage à l’aide des mêmes chaînes de liste d’extensions de fichiers que les boîtes de dialog ouvertes GUI, par exemple:

 ".exe,.pdb".Split(',', ';', '|').SelectMany(_ => Directory.EnumerateFiles(".", "*" + _, searchOptions) 

Emballé:

  public static IEnumerable EnumerateFilesFilter(ssortingng path, ssortingng filesFilter, SearchOption searchOption = SearchOption.TopDirectoryOnly) { return filesFilter.Split(',', ';', '|').SelectMany(_ => Directory.EnumerateFiles(path, "*" + _, searchOption)); }