Сведения о вопросе

LiKIY

23:04, 26th August, 2020

Теги

c#   file   recursion    

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

Просмотров: 402   Ответов: 7

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

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

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

EDIT: если это невозможно сделать без рекурсии и повторения самого себя, то как это лучше всего сделать?



  Сведения об ответе

park

13:45, 23rd August, 2020

Вы должны использовать Directory.GetFiles(path, searchPattern, SearchOption) перегрузку Directory.GetFiles().

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

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

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

return files.Length;

EDIT: в качестве альтернативы вы можете использовать метод Directory.EnumerateFiles

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


  Сведения об ответе

appple

02:24, 23rd August, 2020

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

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


  Сведения об ответе

davran

19:54, 1st August, 2020

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

Directory.GetFiles Метод (Строка, Строка, SearchOption )

а этот член SearchOption:

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

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


  Сведения об ответе

DAAA

15:43, 23rd August, 2020

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

    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


  Сведения об ответе

P_S_S

17:24, 13th August, 2020

При использовании рекурсии ваш 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;
  }

Хотя решение Джона могло быть и лучше.


  Сведения об ответе

+-*/

17:04, 11th August, 2020

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

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


  Сведения об ответе

PHPH

19:34, 6th August, 2020

Кто-то должен сделать итерационную часть.

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться