Rechercher le nombre de fichiers avec une extension spécifique, dans tous les sous-répertoires

StackOverflow https://stackoverflow.com/questions/27570

  •  09-06-2019
  •  | 
  •  

Question

Existe-t-il un moyen de trouver le nombre de fichiers d'un type spécifique sans avoir à parcourir tous les résultats dans une méthode Directory.GetFiles() ou similaire ?Je recherche quelque chose comme ceci :

int ComponentCount = MagicFindFileCount(@"c:\windows\system32", "*.dll");

Je sais que je peux créer une fonction récursive pour appeler Directory.GetFiles , mais ce serait beaucoup plus propre si je pouvais le faire sans toutes les itérations.

MODIFIER: S'il n'est pas possible de le faire sans récursion et itération, quelle serait la meilleure façon de le faire ?

Était-ce utile?

La solution

Vous devriez utiliser le Directory.GetFiles (chemin, searchPattern, SearchOption) surcharge de Directory.GetFiles().

Path spécifie le chemin, searchPattern spécifie vos caractères génériques (par exemple, *, *.format) et SearchOption fournit la possibilité d'inclure des sous-répertoires.

La propriété Longueur du tableau de retour de cette recherche fournira le nombre de fichiers approprié pour votre modèle et option de recherche particuliers :

string[] files = directory.GetFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories);

return files.Length;

MODIFIER: Alternativement, vous pouvez utiliser Méthode Directory.EnumerateFiles

return Directory.EnumerateFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories).Count();

Autres conseils

La méthode la plus simple serait d'utiliser Linq :

var fileCount = (from file in Directory.EnumerateFiles(@"H:\iPod_Control\Music", "*.mp3", SearchOption.AllDirectories)
                    select file).Count();

Vous pouvez utiliser cette surcharge de GetFiles :

Méthode Directory.getFiles (String, String, SearchOption)

et ce membre de SearchOption :

Tous les répertoires - Comprend le répertoire actuel et tous les sous-répertoires d'une opération de recherche.Cette option comprend des points de répartition comme les lecteurs montés et les liens symboliques dans la recherche.

GetFiles renvoie un tableau de chaînes afin que vous puissiez simplement obtenir la longueur qui correspond au nombre de fichiers trouvés.

Je cherchais une version plus optimisée.Comme je ne l'ai pas trouvé, j'ai décidé de le coder et de le partager ici :

    public static int GetFileCount(string path, string searchPattern, SearchOption searchOption)
    {
        var fileCount = 0;
        var fileIter = Directory.EnumerateFiles(path, searchPattern, searchOption);
        foreach (var file in fileIter)
            fileCount++;
        return fileCount;
    }

Toutes les solutions utilisant GetFiles/GetDirectories sont assez lentes car tous ces objets doivent être créés.En utilisant l'énumération, il ne crée aucun objet temporaire (FileInfo/DirectoryInfo).

voir Remarques http://msdn.microsoft.com/en-us/library/dd383571.aspx pour plus d'informations

En utilisant la récursivité, votre MagicFindFileCount ressemblerait à ceci :

private int MagicFindFileCount( string strDirectory, string strFilter ) {
     int nFiles = Directory.GetFiles( strDirectory, strFilter ).Length;

     foreach( String dir in Directory.GetDirectories( strDirectory ) ) {
        nFiles += GetNumberOfFiles(dir, strFilter);
     }

     return nFiles;
  }

Cependant La solution de Jon pourrait être le meilleur.

J'ai une application qui génère le nombre de répertoires et de fichiers dans un répertoire parent.Certains répertoires contiennent des milliers de sous-répertoires contenant chacun des milliers de fichiers.Pour ce faire tout en conservant une interface utilisateur réactive, je procède comme suit (envoyer le chemin à ADirectoryPathWasSelected méthode):

public class DirectoryFileCounter
{
    int mDirectoriesToRead = 0;

    // Pass this method the parent directory path
    public void ADirectoryPathWasSelected(string path)
    {
        // create a task to do this in the background for responsive ui
        // state is the path
        Task.Factory.StartNew((state) =>
        {
            try
            {
                // Get the first layer of sub directories
                this.AddCountFilesAndFolders(state.ToString())


             }
             catch // Add Handlers for exceptions
             {}
        }, path));
    }

    // This method is called recursively
    private void AddCountFilesAndFolders(string path)
    {
        try
        {
            // Only doing the top directory to prevent an exception from stopping the entire recursion
            var directories = Directory.EnumerateDirectories(path, "*.*", SearchOption.TopDirectoryOnly);

            // calling class is tracking the count of directories
            this.mDirectoriesToRead += directories.Count();

            // get the child directories
            // this uses an extension method to the IEnumerable<V> interface,
           // which will run a function on an object. In this case 'd' is the 
           // collection of directories
            directories.ActionOnEnumerable(d => AddCountFilesAndFolders(d));
        }
        catch // Add Handlers for exceptions
        {
        }
        try
        {
            // count the files in the directory
            this.mFilesToRead += Directory.EnumerateFiles(path).Count();
        }
        catch// Add Handlers for exceptions
        { }
    }
}
// Extension class
public static class Extensions
{ 
    // this runs the supplied method on each object in the supplied enumerable
    public static void ActionOnEnumerable<V>(this IEnumerable<V> nodes,Action<V> doit)
    {

        foreach (var node in nodes)
        {   
            doit(node);
        }
    }
}

Quelqu'un doit faire la partie itérative.

AFAIK, une telle méthode n'existe déjà pas dans .NET, donc je suppose que quelqu'un doit être vous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top