Trova il numero di file con una determinata estensione, in tutte le sottodirectory

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

  •  09-06-2019
  •  | 
  •  

Domanda

C'è un modo per trovare il numero di file di un tipo specifico, senza dover scorrere tutti i risultati inn una Directory.GetFiles() o un metodo simile?Sto cercando qualcosa di simile a questo:

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

So che posso fare una funzione ricorsiva per chiamare Directory.GetFiles , ma sarebbe molto di più se ho potuto fare questo senza tutte le iterazioni.

EDIT: Se non è possibile fare questo senza recursing e l'iterazione di te, quale sarebbe il modo migliore per farlo?

È stato utile?

Soluzione

Si dovrebbe usare il Directory.GetFiles(percorso, searchPattern, SearchOption) sovraccarico di Directory.GetFiles().

Il percorso consente di specificare il percorso, searchPattern specifica il tuo caratteri jolly (ad esempio, *, *.formato) e SearchOption fornisce l'opzione per includere le sottocartelle.

La Lunghezza della proprietà di return array di questa ricerca è di fornire il corretto numero di file per il vostro particolare modello di ricerca e di opzione:

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

return files.Length;

EDIT: In alternativa, è possibile utilizzare Directory.EnumerateFiles metodo

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

Altri suggerimenti

Il più destro metodo woud essere di utilizzo di linq:

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

È possibile utilizzare questo sovraccarico di GetFiles:

Directory.Metodo GetFiles (String, Stringa, SearchOption)

e a questo membro della SearchOption:

AllDirectories - Include la corrente directory e tutte le sottodirectory in un'operazione di ricerca.Questa opzione include i punti di analisi, come montato le unità e i link simbolici nella di ricerca.

GetFiles restituisce un array di stringa, in modo che si possa ottenere la Lunghezza che è il numero di file trovati.

Ero alla ricerca di una versione ottimizzata.Visto che non ho trovato, ho deciso di codice e condivido qui:

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

Tutte le soluzioni utilizzando il metodo GetFiles/GetDirectories sono un po ' lento, dato che tutti questi oggetti devono essere creati.Utilizzando l'enumerazione, non crea tutti gli oggetti temporanei (FileInfo/DirectoryInfo).

vedere le Note http://msdn.microsoft.com/en-us/library/dd383571.aspx per ulteriori informazioni

Utilizzando la ricorsione tuo MagicFindFileCount sarebbe simile a questa:

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

Se Jon soluzione potrebbe essere il migliore.

Ho un app che genera conta delle directory e dei file nella directory principale.Alcune directory contengono migliaia di sub directory con migliaia di file in ogni.Per fare questo, pur mantenendo un reattivo ui faccio la seguente ( l'invio del percorso ADirectoryPathWasSelected il metodo):

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

Qualcuno ha a che fare l'iterazione di parte.

Per quanto ne so, non esiste un metodo presente in .NET già, mi sa tanto che qualcuno deve essere voi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top