Encuentre la cantidad de archivos con una extensión específica, en todos los subdirectorios

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

  •  09-06-2019
  •  | 
  •  

Pregunta

¿Hay alguna manera de encontrar la cantidad de archivos de un tipo específico sin tener que recorrer todos los resultados en Directory.GetFiles() o un método similar?Estoy buscando algo como esto:

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

Sé que puedo crear una función recursiva para llamar a Directory.GetFiles, pero sería mucho más limpio si pudiera hacerlo sin tantas iteraciones.

EDITAR: Si no es posible hacer esto sin recurrir e iterar usted mismo, ¿cuál sería la mejor manera de hacerlo?

¿Fue útil?

Solución

Deberías usar el Directory.GetFiles(ruta, patrón de búsqueda, opción de búsqueda) sobrecarga de Directory.GetFiles().

Path especifica la ruta, searchPattern especifica sus comodines (por ejemplo, *, *.format) y SearchOption proporciona la opción de incluir subdirectorios.

La propiedad Longitud de la matriz de retorno de esta búsqueda proporcionará el recuento de archivos adecuado para su patrón y opción de búsqueda particulares:

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

return files.Length;

EDITAR: Alternativamente puedes usar Método Directory.EnumerateFiles

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

Otros consejos

El método más ingenioso sería utilizar linq:

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

Puedes usar esta sobrecarga de GetFiles:

Directorio.getFiles Method (String, String, SearchOption)

y este miembro de SearchOption:

Todos los directorios - Incluye el directorio actual y todos los subdirectorios en una operación de búsqueda.Esta opción incluye puntos de reparación como unidades montadas y enlaces simbólicos en la búsqueda.

GetFiles devuelve una matriz de cadenas para que pueda obtener la Longitud, que es la cantidad de archivos encontrados.

Estaba buscando una versión más optimizada.Como no lo encontré, decidí codificarlo y compartirlo aquí:

    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;
    }

Todas las soluciones que utilizan GetFiles/GetDirectories son un poco lentas ya que es necesario crear todos esos objetos.Al utilizar la enumeración, no crea ningún objeto temporal (FileInfo/DirectoryInfo).

ver las observaciones http://msdn.microsoft.com/en-us/library/dd383571.aspx para más información

Usando recursividad tu MagicFindFileCount se vería así:

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;
  }

Aunque La solución de jon podría ser el mejor.

Tengo una aplicación que genera recuentos de directorios y archivos en un directorio principal.Algunos de los directorios contienen miles de subdirectorios con miles de archivos en cada uno.Para hacer esto mientras mantengo una interfaz de usuario receptiva, hago lo siguiente (enviar la ruta a Se seleccionó una ruta de directorio método):

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

Alguien tiene que hacer la parte iterativa.

AFAIK, ya no existe tal método en .NET, así que supongo que alguien tiene que ser usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top