Trova il numero di file con una determinata estensione, in tutte le sottodirectory
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?
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:
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.