Рекурсивно считать строки в файлах в папках - PullRequest
1 голос
/ 05 февраля 2010

В C #, как лучше всего подсчитать общее количество строк во всех файлах в каталоге и во всех его подкаталогах?

Очевидный ответ - создать рекурсивную функцию для просмотра всех каталогов и использовать стратегию из этого вопроса для подсчета строк в каждом файле. Есть ли лучший / более простой способ?

Ответы [ 7 ]

6 голосов
/ 05 февраля 2010

Есть ли лучший / более простой способ?

Нет, (в общем) нет лучшего способа получить количество строк в файле, чем их подсчет.

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

1 голос
/ 05 февраля 2010

Вот LINQy способ сделать это:

string path = @"C:\TonsOfTextFiles";
int totalLines = (from file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
                    let fileText = File.ReadAllLines(file)
                    select fileText.Length).Sum();
1 голос
/ 05 февраля 2010

Стратегия, которую вы описали, работает хорошо. Альтернативный подход вместо рекурсивной функции (в основном DFS) заключается в использовании BFS. Что-то вроде:

int CountLines(string path)
{
    var queue = new Queue<string>();
    queue.Enqueue(path);
    int count = 0;
    while (queue.Count > 0) {
        string dir = queue.Dequeue();
        foreach (var subdir in Directory.GetDirectories(dir))
            queue.Enqueue(subdir);
        foreach (var file in Directory.GetFiles(dir))
            count += GetLineCount(file); 
    }
    return count;
}
1 голос
/ 05 февраля 2010

Нет лучшего способа. Обход структуры каталогов для всех подкаталогов по своей природе поддается рекурсивному выполнению. Что касается подсчета строк в файле, у вас действительно нет другого выбора, кроме как открыть файл и сосчитать строки. Обратите внимание, что вам нужно знать, как взорвать ваш стек, поэтому вам, возможно, придется вручную моделировать рекурсию, используя Queue.

Поскольку этот метод относительно легко кодировать правильно, четко и кратко, я думаю, что это то, что вам следует сделать, и перейти к добавлению ценности в другом месте.

0 голосов
/ 05 февраля 2010

Пожалуйста, Боже, прости меня:

@echo off
set sum=0
for /r %%f in (*.cs) do find /v /c "$$some nonsense string$$" %%f >> test.dat
for /f "tokens=3 delims=:" %%i in (test.dat) do set /a sum += %%i
echo total lines = %sum%
del test.dat

Это не C #, но это весело.

РЕДАКТИРОВАТЬ: Это может быть более эффективным с точки зрения памяти, так как он не использует ReadAllLines, но по одному:

string basePath = @"C:\some\path";
Console.WriteLine(
    Directory.GetFiles(basePath, "*.cs", SearchOption.AllDirectories)
        .Sum(file => 
        {
            int lines = 0;
            using (StreamReader reader = new StreamReader(file))
                while(reader.ReadLine() != null) lines++;
            return lines;
        }));
0 голосов
/ 05 февраля 2010

Для поиска файлов, почему бы просто не использовать что-то вроде:

Directory.GetFiles("C:/some/path", "*.txt", SearchOption.AllDirectories);

Это даст вам результаты рекурсивного поиска.

0 голосов
/ 05 февраля 2010

Я думаю, что этот пост достаточно объясняет последнюю часть вашего вопроса. Что касается обхода каталога, проверьте это http://dotnetperls.com/recursively-find-files

ОБНОВЛЕНИЕ: здесь есть абстракция: я очень надеялся, что вы прочтете ссылку, но здесь она http://dotnetperls.com/recursive-file-list-1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...