在C#中,获取目录及其所有子目录中所有文件中总行数的最佳方法是什么?
显而易见的答案是使递归函数遍历所有目录并使用this question中的策略来计算每个文件中的行。有更好/更简单的方法吗?
答案 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;
}));