Найдите количество файлов с определенным расширением во всех подкаталогах

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

  •  09-06-2019
  •  | 
  •  

Вопрос

Есть ли способ найти количество файлов определенного типа без необходимости перебирать все результаты в каталоге.GetFiles() или аналогичный метод?Я ищу что-то вроде этого:

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

Я знаю, что могу создать рекурсивную функцию для вызова Directory.GetFiles , но было бы намного чище, если бы я мог сделать это без всех итераций.

Редактировать: Если невозможно сделать это без повторения и итерации самостоятельно, каков был бы наилучший способ сделать это?

Это было полезно?

Решение

Вам следует использовать Каталог.GetFiles(путь, searchPattern, SearchOption) перегрузка каталога.GetFiles().

Path указывает путь, searchPattern указывает ваши подстановочные знаки (например, *, *.format), а SearchOption предоставляет возможность включать подкаталоги.

Свойство Length возвращаемого массива этого поиска предоставит правильное количество файлов для вашего конкретного шаблона поиска и опции:

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

return files.Length;

Редактировать: В качестве альтернативы вы можете использовать Каталог.Метод перечисления файлов

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

Другие советы

Самым простым методом было бы использовать linq:

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

Вы можете использовать эту перегрузку GetFiles:

Каталог.Метод получения файлов (String, Строка, параметр поиска)

и этот участник SearchOption:

Все каталоги - Включает текущий каталог и все подкаталоги в операции поиска.Этот параметр включает в себя точки повторной проверки, такие как подключенные диски и символические ссылки в поиске.

GetFiles возвращает массив строк, так что вы можете просто получить длину, которая равна количеству найденных файлов.

Я искал более оптимизированную версию.Поскольку я не нашел его, я решил закодировать и поделиться им здесь:

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

Все решения, использующие GetFiles / GetDirectories, являются довольно медленными, поскольку все эти объекты должны быть созданы.Используя перечисление, оно не создает никаких временных объектов (FileInfo /DirectoryInfo).

смотрите Примечания http://msdn.microsoft.com/en-us/library/dd383571.aspx для получения дополнительной информации

При использовании рекурсии ваш MagicFindFileCount будет выглядеть следующим образом:

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

Хотя Решение Джона возможно, это было бы лучше.

У меня есть приложение, которое генерирует количество каталогов и файлов в родительском каталоге.Некоторые каталоги содержат тысячи подкаталогов с тысячами файлов в каждом.Чтобы сделать это, сохраняя адаптивный пользовательский интерфейс, я делаю следующее ( отправляя путь к Выбранный adirectorypath способ):

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

Кто-то должен выполнить повторяющуюся часть.

AFAIK, в .NET такого метода уже нет, так что я предполагаю, что кем-то должен быть ты.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top