使用递归来执行此操作的主要问题是:
如果您的树的深度太大,您可能没有足够的堆栈空间。虽然拥有那么深的文件系统结构并不常见,但这并非不可想象。
您使用的内存超过了所需的内存,因为您在堆栈帧中保存了许多可以避免的数据。
至于渐近复杂度,无论其大小如何,每个节点都执行一次操作,因此它的复杂度为 O(n),其中 n 是所有节点,而不是任何给定深度的节点。
但是,您可以使用内置方法遍历整个树来更有效地处理所有这些。即使您的解决方案是非递归的,它也会比您提出的解决方案更有效,只需使用:
foreach(string file in Directory.EnumerateFiles(path, "*",
SearchOption.AllDirectories))
{
System.IO.File.AppendAllText("e:\\personal\\tests.txt",
System.IO.Path.GetFileName(file) + ":" + rootFolder + "\n")
}
虽然该解决方案可能不使用递归,但如果您想知道如何自己编写非递归树遍历,则可以使用如下通用方法:
public static IEnumerable<T> Traverse<T>(
this IEnumerable<T> source
, Func<T, IEnumerable<T>> childrenSelector)
{
var stack = new Stack<T>(source);
while (stack.Any())
{
var next = stack.Pop();
yield return next;
foreach (var child in childrenSelector(next))
stack.Push(child);
}
}
在你的情况下,调用它可能看起来像这样:
var allFiles = new[] { new DirectoryInfo(path) }
.Traverse(directory => directory.EnumerateDirectories())
.Select(directory => directory.EnumerateFiles());
请注意,虽然这对于遍历不提供完整遍历的内置方式的树来说很好,但这通常对于遍历文件系统来说并不理想。您应该使用第一个解决方案,因为它已经针对遍历文件系统的特殊情况进行了高度优化。