以递归方式计算文件夹中文件中的行

时间:2010-02-04 22:21:29

标签: c# file recursion

在C#中,获取目录及其所有子目录中所有文件中总行数的最佳方法是什么?

显而易见的答案是使递归函数遍历所有目录并使用this question中的策略来计算每个文件中的行。有更好/更简单的方法吗?

7 个答案:

答案 0 :(得分:6)

  

有更好/更简单的方法吗?

不,(通常)没有更好的方法来获取文件中的行数而不是计算它们。

为了找到所有文件中的总行数,您必须在某个时刻获取每个文件中的总行数。真的没办法解决这个问题。

答案 1 :(得分:1)

没有更好的方法。遍历目录结构到所有子目录本身就有助于递归完成。至于计算文件中的行,你真的别无选择,只能打开文件并计算行数。请注意,您确实需要注意炸毁堆栈,因此您可能必须使用Queue手动模拟递归。

由于这种方法编码正确,清晰而简洁,相对容易,我认为这是你应该做的,然后继续在其他地方增加价值。

答案 2 :(得分:1)

您描述的策略运作良好。替代递归函数(基本上是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;
}

答案 3 :(得分:1)

这是一种LINQy方式:

string path = @"C:\TonsOfTextFiles";
int totalLines = (from file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
                    let fileText = File.ReadAllLines(file)
                    select fileText.Length).Sum();

答案 4 :(得分:0)

我认为这篇文章足以解释你问题的后半部分。就目录遍历而言,请查看此http://dotnetperls.com/recursively-find-files

更新:对此有一个抽象:我真的希望你能阅读这个链接,但这里是http://dotnetperls.com/recursive-file-list-1

答案 5 :(得分:0)

为了找到文件,为什么不使用以下内容:

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

这将为您提供递归搜索的结果。

答案 6 :(得分:0)

请原谅我,原谅我:

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