408 votes

Pouvez-vous appeler Répertoire.GetFiles() avec plusieurs filtres?

Je suis en train d'utiliser l' Directory.GetFiles() méthode pour récupérer une liste de fichiers de plusieurs types, tels que l' mp3s et jpg'. 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?

603voto

Christoffer Lette Points 4739

Pour .NET 4.0 et versions ultérieures,

var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

Pour les versions antérieures de .NET,

var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

edit: Merci de lire les commentaires. L'amélioration que Paul Farry suggère, et la mémoire/problème de performance que les Chrétiens.K points sont à la fois très important.

68voto

Albert Points 468

Comment à ce sujet:

private static string[] GetFiles(string sourceFolder, string filters, System.IO.SearchOption searchOption)
{
   return filters.Split('|').SelectMany(filter => System.IO.Directory.GetFiles(sourceFolder, filter, searchOption)).ToArray();
}

Je l'ai trouvé ici (dans les commentaires): http://msdn.microsoft.com/en-us/library/wz42302f.aspx

40voto

jnoreiga Points 684

Si 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.

string supportedExtensions = "*.jpg,*.gif,*.png,*.bmp,*.jpe,*.jpeg,*.wmf,*.emf,*.xbm,*.ico,*.eps,*.tif,*.tiff,*.g01,*.g02,*.g03,*.g04,*.g05,*.g06,*.g07,*.g08";
foreach (string imageFile in Directory.GetFiles(_tempDirectory, "*.*", SearchOption.AllDirectories).Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower())))
{
    //do work here
}

35voto

drzaus Points 3344

pour

var exts = new[] { "mp3", "jpg" };

Vous pouvez:

public IEnumerable<string> FilterFiles(string path, params string[] exts) {
    return
        Directory
        .EnumerateFiles(path, "*.*")
        .Where(file => exts.Any(x => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)));
}

Mais le véritable avantage de la EnumerateFiles s'affiche lorsque vous fractionnez les filtres et fusionner les résultats:

public IEnumerable<string> FilterFiles(string path, params string[] exts) {
    return 
        exts.Select(x => "*." + x) // turn into globs
        .SelectMany(x => 
            Directory.EnumerateFiles(path, x)
            );
}

Cela devient un peu plus rapide si vous n'avez pas à les transformer en boules (c - 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 )

12voto

Dave Rael Points 1241

Une autre façon d'utiliser Linq, mais sans avoir à retourner le tout et filtrer dans la mémoire.

var files = Directory.GetFiles("C:\\path", "*.mp3", SearchOption.AllDirectories).Union(Directory.GetFiles("C:\\path", "*.jpg", SearchOption.AllDirectories));

C'est en fait 2 appels à l' GetFiles(), mais je pense que c'est cohérent avec l'esprit de la question et les retourne dans un énumérable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X