Pouvez-vous appeler Directory.GetFiles () avec plusieurs filtres?

354

J'essaie d'utiliser la Directory.GetFiles()méthode pour récupérer une liste de fichiers de plusieurs types, tels que mp3«et jpg». J'ai essayé les deux solutions suivantes sans succès:

Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);

Existe-t-il un moyen de le faire en un seul appel?

Jason Z
la source
3
En guise de remarque, l'utilisation du modèle de recherche GetFiles pour filtrer l'extension n'est pas sûre.Par exemple, vous avez deux fichiers Test1.xls et Test2.xlsx et vous souhaitez filtrer le fichier xls en utilisant le modèle de recherche * .xls, mais GetFiles renvoie les deux Test1 .xls et Test2.xlsx. Lire la section Note pour plus d'informations
kiran
Alors, comment éviter cela?
Supports
2
@kiran Comment est-ce que ce n'est pas sûr? Cela ressemble à une fonctionnalité plutôt qu'à un bogue.
Kyle Delaney

Réponses:

521

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"));

modifier: Veuillez lire les commentaires. L'amélioration suggérée par Paul Farry et le problème de mémoire / performance que Christian.K souligne sont tous deux très importants.

Christoffer Lette
la source
10
Mec, je dois penser plus souvent en termes de LINQ. Bonne solution!
Ken Pespisa
61
Assurez-vous simplement de bien comprendre les implications: cela retournera tous les fichiers dans un tableau de chaînes, puis les filtrera par les extensions que vous spécifiez. Ce n'est peut-être pas un gros problème si "C: \ Path" n'a pas beaucoup de fichiers en dessous, mais cela peut être un problème de mémoire / performances sur "C: \" ou quelque chose comme ça.
Christian.K
24
... 2 ans plus tard: Code sympa, mais attention, si vous avez un fichier qui se termine par .JPG, il ne le fera pas. Mieux ajouters.ToLower().Endswith...
Stormenet
107
vous pouvez simplement utilisers.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Paul Farry
119
Notez qu'avec .NET 4.0, vous pouvez remplacer Directory.GetFilespar Directory.EnumerateFiles, msdn.microsoft.com/en-us/library/dd383571.aspx , ce qui évitera les problèmes de mémoire mentionnés par @ Christian.K.
Jim Mischel
60

Que dis-tu de ça:

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

Albert
la source
Je suppose que cela évite les pièges de mémoire potentiels de la réponse la mieux notée? Dans ce cas, il devrait être évalué plus haut!
Dan W
11
@DanW La réponse la mieux notée pèse sûrement sur la mémoire, mais je pense que cela ne devrait pas être un problème. J'ai aussi aimé cette réponse, mais c'est en fait (beaucoup) plus lent que la réponse acceptée. Vérifiez ce SpeedTest
OttO
Merci. Heureux de voir que c'est seulement deux fois plus lent - je vais m'en tenir à cela, je pense.
Dan W
7
Il n'est que deux fois plus lent s'il n'y a que deux extensions. Si vous avez une liste d'extensions X, ce sera X fois plus lent. Parce qu'ici, vous appelez la fonction Directory.GetFiles plusieurs fois, alors que dans l'autre solution, elle n'est appelée qu'une seule fois.
Oscar Hermosilla
1
@OscarHermosilla On peut utiliser Parallel.ForEachpour les mettre en parallèle
FindOutIslamNow
33

Si vous avez une grande liste d'extensions à vérifier, vous pouvez utiliser ce qui suit. Je ne voulais pas créer beaucoup d'instructions OR, j'ai donc modifié ce que 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
}
jnoreiga
la source
Aidez-moi avec ceci s'il vous plaît ... Lorsque j'imprime imageFile, il donne le chemin total de celui-ci.
Naresh
1
System.IO.Path.GetFileName (imageFile)
jnoreiga
Path.GetExtensionrenvoie '.ext', pas '* .ext' (au moins dans 3.5+).
nullable
2
Pour info: vous avez besoin de System.Linq pour .where (
jnoreiga
1
Il y a un défaut potentiel. Nous avons depuis longtemps dépassé les jours où les extensions doivent avoir exactement trois caractères. Supposons que vous rencontriez un fichier avec .abcet que les extensions prises en charge le contiennent .abcd. Correspondra, mais il ne devrait pas. Pour réparer: supportedExtensions = ".jpg|.abcd|";avec .Contains(Path.GetExtension(s).ToLower() + "|"). Autrement dit, incluez votre caractère séparateur dans le test. IMPORTANT: votre caractère séparateur doit également se trouver après la dernière entrée dans les exceptions prises en charge.
ToolmakerSteve
31

pour

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

Vous pourriez:

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 EnumerateFiless'affiche lorsque vous divisez les filtres et fusionnez 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 globes (c'est-à-dire exts = new[] {"*.mp3", "*.jpg"}déjà).

Évaluation des performances basée sur le test LinqPad suivant (remarque: Perfrépète simplement le délégué 10000 fois) https://gist.github.com/zaus/7454021

(republié et étendu à partir de 'duplicate' car cette question ne demandait spécifiquement aucun LINQ: Multiple file-extensions searchPattern for System.IO.Directory.GetFiles )

drzaus
la source
que voulez-vous dire par "j'obtiens un peu plus vite si vous n'avez pas à les transformer en globes"? Est-ce O (1) ou O (n) (en ce qui concerne le nombre de fichiers, pas le nombre d'extensions)? J'aurais deviné que c'est O (1) (ou O (n) en ce qui concerne le nombre d'extensions) et probablement quelque part dans la plage de quelques cycles de processeur ... Si c'est le cas, c'est probablement - en termes de performances - négligeable
BatteryBackupUnit
@BatteryBackupUnit oui avec 10 000 répétitions contre 2 extensions, la différence glob vs str est de 3 ms, donc oui techniquement négligeable (voir le lien des résultats de perf), mais ne sachant pas combien d'extensions vous devez filtrer pour je me suis dit qu'il valait la peine de souligner qu'il y avait un différence; je vous laisse le soin de décider si une "utilisation simplifiée" (ie .FilterFiles(path, "jpg", "gif")) est meilleure que des "globes explicites" (ie .FilterFiles(path, "*.jpg", "*.gif")).
drzaus
parfait merci. Désolé, j'ai en quelque sorte ignoré ce lien github. Je devrais peut-être adapter les paramètres de couleur de mon écran :)
BatteryBackupUnit
Est-ce que cela prend en charge l'extension en majuscules comme le cul .JPG ou .MKV?
Wahyu
1
Le défaut de la solution SelectMany est qu'elle itérera sur tous les fichiers une fois par extension de fichier transmise.
17 du 26
16

Je sais que c'est une vieille question mais LINQ: (.NET40 +)

var files = Directory.GetFiles("path_to_files").Where(file => Regex.IsMatch(file, @"^.+\.(wav|mp3|txt)$"));
Icehunter
la source
3
Bonne idée. Pensez à utiliser file.ToLower()pour faire correspondre facilement les extensions majuscules. Et pourquoi ne pas extraire l'extension en premier, afin que Regex n'ait pas à examiner l'intégralité du chemin: Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
ToolmakerSteve
13

Il existe également une solution de descente qui semble ne pas avoir de mémoire ou de surcharge de performances et être assez élégante:

string[] filters = new[]{"*.jpg", "*.png", "*.gif"};
string[] filePaths = filters.SelectMany(f => Directory.GetFiles(basePath, f)).ToArray();
Bas1l
la source
1
Je suppose que je pourrais le modifier pour qu'il accepte un nombre illimité d'extensions inconnu avec une nouvelle variable de chaîne et une fonction Split. Mais même alors, comment est-ce mieux que la solution de jnoreiga? Est-ce plus rapide? Moins de mémoire consommée?
Supports
1
Il y a un compromis. Cette approche appelle plusieurs fois GetFiles, une par filtre. Ces appels multiples peuvent représenter une "surcharge de performances" importante dans certaines situations. Il présente l'avantage important que chaque GetFiles ne renvoie qu'un tableau avec les chemins de fichiers correspondants . Je m'attendrais à ce que ce soit généralement un bon résultat de performance, peut-être même une performance supérieure , mais cela doit être testé. Si GetFiles est nettement plus rapide que EnumerateFiles, cela peut être la meilleure approche à ce jour. Notez également que le ".ToArray ()" final peut être omis lorsque IEnumerable est utilisable directement.
ToolmakerSteve
11

Une autre façon d'utiliser Linq, mais sans avoir à tout renvoyer et filtrer cela en mémoire.

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

Il s'agit en fait de 2 appels à GetFiles(), mais je pense que cela correspond à l'esprit de la question et les renvoie en un seul énumérable.

Dave Rael
la source
Pourquoi utiliser Linq, alors? Serait-ce plus rapide que d'utiliser une liste et une plage de valeurs?
ThunderGr
1
je ne sais pas ce qui serait plus rapide et je ne pense pas que ce soit une question importante. pour presque tous les endroits où vous utiliseriez le code pour toute solution à ce problème, la différence de performances serait négligeable. la question devrait être de savoir ce qui est plus lisible pour faciliter la maintenabilité du code à l'avenir. Je pense que c'est une réponse raisonnable parce qu'elle met dans une seule ligne source, qui, je pense, fait partie de ce que la question désire, les appels nécessaires et exprime clairement l'intention de cette ligne. list and addrange est distrayant avec plusieurs étapes pour accomplir la même chose.
Dave Rael
7

Nan. Essayez ce qui suit:

List<string> _searchPatternList = new List<string>();
    ...
    List<string> fileList = new List<string>();
    foreach ( string ext in _searchPatternList )
    {
        foreach ( string subFile in Directory.GetFiles( folderName, ext  )
        {
            fileList.Add( subFile );
        }
    }

    // Sort alpabetically
    fileList.Sort();

    // Add files to the file browser control    
    foreach ( string fileName in fileList )
    {
        ...;
    }

Tiré de: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx

Pas moi
la source
7

Laisser

var set = new HashSet<string> { ".mp3", ".jpg" };

alors

Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
         .Where(f => set.Contains(
             new FileInfo(f).Extension,
             StringComparer.OrdinalIgnoreCase));

ou

from file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
from ext in set
where String.Equals(ext, new FileInfo(file).Extension, StringComparison.OrdinalIgnoreCase)
select file;
abatishchev
la source
getfiles n'a pas affiché la surcharge u.
nawfal
5

Je ne peux pas utiliser la .Whereméthode car je programme en .NET Framework 2.0 (Linq n'est pris en charge que dans .NET Framework 3.5+).

Le code ci-dessous n'est pas sensible à la casse (donc .CaBou .cabsera également répertorié).

string[] ext = new string[2] { "*.CAB", "*.MSU" };

foreach (string found in ext)
{
    string[] extracted = Directory.GetFiles("C:\\test", found, System.IO.SearchOption.AllDirectories);

    foreach (string file in extracted)
    {
        Console.WriteLine(file);
    }
}
jaysponsored
la source
4

La fonction suivante recherche sur plusieurs modèles, séparés par des virgules. Vous pouvez également spécifier une exclusion, par exemple: "! Web.config" recherchera tous les fichiers et exclura "web.config". Les motifs peuvent être mélangés.

private string[] FindFiles(string directory, string filters, SearchOption searchOption)
{
    if (!Directory.Exists(directory)) return new string[] { };

    var include = (from filter in filters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) where !string.IsNullOrEmpty(filter.Trim()) select filter.Trim());
    var exclude = (from filter in include where filter.Contains(@"!") select filter);

    include = include.Except(exclude);

    if (include.Count() == 0) include = new string[] { "*" };

    var rxfilters = from filter in exclude select string.Format("^{0}$", filter.Replace("!", "").Replace(".", @"\.").Replace("*", ".*").Replace("?", "."));
    Regex regex = new Regex(string.Join("|", rxfilters.ToArray()));

    List<Thread> workers = new List<Thread>();
    List<string> files = new List<string>();

    foreach (string filter in include)
    {
        Thread worker = new Thread(
            new ThreadStart(
                delegate
                {
                    string[] allfiles = Directory.GetFiles(directory, filter, searchOption);
                    if (exclude.Count() > 0)
                    {
                        lock (files)
                            files.AddRange(allfiles.Where(p => !regex.Match(p).Success));
                    }
                    else
                    {
                        lock (files)
                            files.AddRange(allfiles);
                    }
                }
            ));

        workers.Add(worker);

        worker.Start();
    }

    foreach (Thread worker in workers)
    {
        worker.Join();
    }

    return files.ToArray();

}

Usage:

foreach (string file in FindFiles(@"D:\628.2.11", @"!*.config, !*.js", SearchOption.AllDirectories))
            {
                Console.WriteLine(file);
            }
Alexander Popov
la source
4
List<string> FileList = new List<string>();
DirectoryInfo di = new DirectoryInfo("C:\\DirName");

IEnumerable<FileInfo> fileList = di.GetFiles("*.*");

//Create the query
IEnumerable<FileInfo> fileQuery = from file in fileList
                                  where (file.Extension.ToLower() == ".jpg" || file.Extension.ToLower() == ".png")
                                  orderby file.LastWriteTime
                                  select file;

foreach (System.IO.FileInfo fi in fileQuery)
{
    fi.Attributes = FileAttributes.Normal;
    FileList.Add(fi.FullName);
}
Rajeesh Kuthuparakkal
la source
file.Extension.ToLower()est une mauvaise pratique.
abatishchev
alors que devons-nous utiliser? @abatishchev
Nitin Sawant
@Nitin:String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
abatishchev
1
En fait, file.Extension.Equals (". Jpg", StringComparison.OrdinalIgnoreCase) est ce que je préfère. Il semble être plus rapide que .ToLower ou .ToUpper, ou du moins disent-ils partout où j'ai cherché. En fait, .Equals est également plus rapide que ==, car == appelle .Equals et vérifie null (car vous ne pouvez pas faire null.Equals (null)).
ThunderGr
4

dans .NET 2.0 (pas Linq):

public static List<string> GetFilez(string path, System.IO.SearchOption opt,  params string[] patterns)
{
    List<string> filez = new List<string>();
    foreach (string pattern in patterns)
    {
        filez.AddRange(
            System.IO.Directory.GetFiles(path, pattern, opt)
        );
    }


    // filez.Sort(); // Optional
    return filez; // Optional: .ToArray()
}

Ensuite, utilisez-le:

foreach (string fn in GetFilez(path
                             , System.IO.SearchOption.AllDirectories
                             , "*.xml", "*.xml.rels", "*.rels"))
{}
Stefan Steiger
la source
4
DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Contents/"));

//Using Union

FileInfo[] files = directory.GetFiles("*.xlsx")
                            .Union(directory
                            .GetFiles("*.csv"))
                            .ToArray();
Nilesh Padhiyar
la source
3

Je viens de trouver une autre façon de le faire. Toujours pas une opération, mais la jeter pour voir ce que les autres en pensent.

private void getFiles(string path)
{
    foreach (string s in Array.FindAll(Directory.GetFiles(path, "*", SearchOption.AllDirectories), predicate_FileMatch))
    {
        Debug.Print(s);
    }
}

private bool predicate_FileMatch(string fileName)
{
    if (fileName.EndsWith(".mp3"))
        return true;
    if (fileName.EndsWith(".jpg"))
        return true;
    return false;
}
Jason Z
la source
3

Qu'en est-il de

string[] filesPNG = Directory.GetFiles(path, "*.png");
string[] filesJPG = Directory.GetFiles(path, "*.jpg");
string[] filesJPEG = Directory.GetFiles(path, "*.jpeg");

int totalArraySizeAll = filesPNG.Length + filesJPG.Length + filesJPEG.Length;
List<string> filesAll = new List<string>(totalArraySizeAll);
filesAll.AddRange(filesPNG);
filesAll.AddRange(filesJPG);
filesAll.AddRange(filesJPEG);
MattyMerrix
la source
2

Faites les extensions que vous voulez une chaîne, c'est-à-dire ".mp3.jpg.wma.wmf", puis vérifiez si chaque fichier contient l'extension souhaitée. Cela fonctionne avec .net 2.0 car il n'utilise pas LINQ.

string myExtensions=".jpg.mp3";

string[] files=System.IO.Directory.GetFiles("C:\myfolder");

foreach(string file in files)
{
   if(myExtensions.ToLower().contains(System.IO.Path.GetExtension(s).ToLower()))
   {
      //this file has passed, do something with this file

   }
}

L'avantage de cette approche est que vous pouvez ajouter ou supprimer des extensions sans modifier le code, c'est-à-dire pour ajouter des images png, il suffit d'écrire myExtensions = ". Jpg.mp3.png".

Evado
la source
il ne sait pas ce que c'ests
Brackets
2
/// <summary>
/// Returns the names of files in a specified directories that match the specified patterns using LINQ
/// </summary>
/// <param name="srcDirs">The directories to seach</param>
/// <param name="searchPatterns">the list of search patterns</param>
/// <param name="searchOption"></param>
/// <returns>The list of files that match the specified pattern</returns>
public static string[] GetFilesUsingLINQ(string[] srcDirs,
     string[] searchPatterns,
     SearchOption searchOption = SearchOption.AllDirectories)
{
    var r = from dir in srcDirs
            from searchPattern in searchPatterns
            from f in Directory.GetFiles(dir, searchPattern, searchOption)
            select f;

    return r.ToArray();
}
A.Ramazani
la source
2

Non ... Je crois que vous devez faire autant d'appels que les types de fichiers que vous souhaitez.

Je créerais moi-même une fonction en prenant un tableau sur les chaînes avec les extensions dont j'ai besoin, puis j'itérerais sur ce tableau en faisant tous les appels nécessaires. Cette fonction retournerait une liste générique des fichiers correspondant aux extensions que j'avais envoyées.

J'espère que cela aide.

sebagomez
la source
1

J'ai eu le même problème et je n'ai pas trouvé la bonne solution, j'ai donc écrit une fonction appelée GetFiles:

/// <summary>
/// Get all files with a specific extension
/// </summary>
/// <param name="extensionsToCompare">string list of all the extensions</param>
/// <param name="Location">string of the location</param>
/// <returns>array of all the files with the specific extensions</returns>
public string[] GetFiles(List<string> extensionsToCompare, string Location)
{
    List<string> files = new List<string>();
    foreach (string file in Directory.GetFiles(Location))
    {
        if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.')+1).ToLower())) files.Add(file);
    }
    files.Sort();
    return files.ToArray();
}

Cette fonction n'appellera Directory.Getfiles()qu'une seule fois.

Par exemple, appelez la fonction comme ceci:

string[] images = GetFiles(new List<string>{"jpg", "png", "gif"}, "imageFolder");

EDIT: Pour obtenir un fichier avec plusieurs extensions, utilisez celui-ci:

/// <summary>
    /// Get the file with a specific name and extension
    /// </summary>
    /// <param name="filename">the name of the file to find</param>
    /// <param name="extensionsToCompare">string list of all the extensions</param>
    /// <param name="Location">string of the location</param>
    /// <returns>file with the requested filename</returns>
    public string GetFile( string filename, List<string> extensionsToCompare, string Location)
    {
        foreach (string file in Directory.GetFiles(Location))
        {
            if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.') + 1).ToLower()) &&& file.Substring(Location.Length + 1, (file.IndexOf('.') - (Location.Length + 1))).ToLower() == filename) 
                return file;
        }
        return "";
    }

Par exemple, appelez la fonction comme ceci:

string image = GetFile("imagename", new List<string>{"jpg", "png", "gif"}, "imageFolder");
Quispie
la source
1

Je me demande pourquoi il y a tant de "solutions" affichées?

Si ma compréhension débutante sur le fonctionnement de GetFiles est correcte, il n'y a que deux options et l'une des solutions ci-dessus peut être réduite à celles-ci:

  1. GetFiles, puis filtre: rapide, mais un tueur de mémoire dû au stockage de la surcharge jusqu'à ce que les filtres soient appliqués

  2. Filtrer pendant que GetFiles: Plus les filtres sont définis, plus lent, mais la faible utilisation de la mémoire car aucune surcharge n'est stockée.
    Ceci est expliqué dans l'un des articles ci-dessus avec un point de repère impressionnant: chaque option de filtre provoque une opération GetFile distincte, de sorte que la même partie du disque dur est lue plusieurs fois.

À mon avis, l'option 1) est meilleure, mais l'utilisation de SearchOption.AllDirectories sur des dossiers comme C: \ utiliserait d'énormes quantités de mémoire.
À cet effet, je ferais simplement une sous-méthode récursive qui passe par tous les sous-dossiers en utilisant l'option 1)

Cela ne devrait provoquer qu'une seule opération GetFiles sur chaque dossier et donc rapide (Option 1), mais n'utilisez qu'une petite quantité de mémoire car les filtres sont appliqués après la lecture de chaque sous-dossier -> la surcharge est supprimée après chaque sous-dossier.

S'il vous plait corrigez moi si je me trompe. Je suis comme je l'ai dit assez nouveau dans la programmation, mais je veux acquérir une meilleure compréhension des choses pour finalement devenir bon dans ce domaine :)

Janis
la source
1

Si vous utilisez VB.NET (ou avez importé la dépendance dans votre projet C #), il existe en fait une méthode pratique qui permet de filtrer pour plusieurs extensions:

Microsoft.VisualBasic.FileIO.FileSystem.GetFiles("C:\\path", Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, new string[] {"*.mp3", "*.jpg"});

Dans VB.NET, cela est accessible via le My-namespace:

My.Computer.FileSystem.GetFiles("C:\path", FileIO.SearchOption.SearchAllSubDirectories, {"*.mp3", "*.jpg"})

Malheureusement, ces méthodes pratiques ne prennent pas en charge une variante évaluée paresseusement comme le Directory.EnumerateFiles()fait.

Crusha K. Rool
la source
C'est facilement la meilleure réponse et pourtant quelque chose de beaucoup plus hacky est la solution acceptée. Je dois aimer SO.
Robbie Coyne
0

je ne sais pas quelle solution est la meilleure, mais j'utilise ceci:

String[] ext = "*.ext1|*.ext2".Split('|');

            List<String> files = new List<String>();
            foreach (String tmp in ext)
            {
                files.AddRange(Directory.GetFiles(dir, tmp, SearchOption.AllDirectories));
            }
elle0087
la source
0

Voici un moyen simple et élégant d'obtenir des fichiers filtrés

var allowedFileExtensions = ".csv,.txt";


var files = Directory.EnumerateFiles(@"C:\MyFolder", "*.*", SearchOption.TopDirectoryOnly)
                .Where(s => allowedFileExtensions.IndexOf(Path.GetExtension(s)) > -1).ToArray(); 
JohnnBlade
la source
-1

Ou vous pouvez simplement convertir la chaîne d'extensions en chaîne ^

vector <string>  extensions = { "*.mp4", "*.avi", "*.flv" };
for (int i = 0; i < extensions.size(); ++i)
{
     String^ ext = gcnew String(extensions[i].c_str());;
     String^ path = "C:\\Users\\Eric\\Videos";
     array<String^>^files = Directory::GetFiles(path,ext);
     Console::WriteLine(ext);
     cout << " " << (files->Length) << endl;
}
user3512661
la source
2
Ceci est c ++ pas c #
Brackets
-1

L'utilisation du modèle de recherche GetFiles pour filtrer l'extension n'est pas sûre !! Par exemple, vous avez deux fichiers Test1.xls et Test2.xlsx et vous souhaitez filtrer le fichier xls en utilisant le modèle de recherche * .xls, mais GetFiles renvoie à la fois Test1.xls et Test2.xlsx Je n'étais pas au courant de cela et j'ai eu une erreur de production environnement lorsque certains fichiers temporaires ont été soudainement traités comme de bons fichiers. Le modèle de recherche était * .txt et les fichiers temporaires étaient nommés * .txt20181028_100753898 Donc, le modèle de recherche ne peut pas être approuvé, vous devez également ajouter une vérification supplémentaire sur les noms de fichiers.

WillyS
la source
Ne répond pas à la question.
Robbie Coyne