文件和文件夹在C#递归上市 [英] Recursively listing of files and folders in C#

查看:120
本文介绍了文件和文件夹在C#递归上市的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写这篇code递归地列出在C#中的文件和文件夹。

I wrote this code to recursively list files and folders in c#.

            var filesInTheCurrentDirectory = System.IO.Directory.GetFiles(rootFolder);
            if (!filesInTheCurrentDirectory.Any() && !System.IO.Directory.GetDirectories(rootFolder).ToList().Any())
            {
                return;
            }

            filesInTheCurrentDirectory.ToList().ForEach(file => System.IO.File.AppendAllText("e:\\personal\\tests.txt", System.IO.Path.GetFileName(file) + ":" + rootFolder + "\n"));
            System.IO.Directory.GetDirectories(rootFolder).ToList().ForEach(recursivePrintFolders);

虽然这只是的的伟大工程,问题是:

While this just works great, the question is:

  1. 我使用递归。就是这样,在 最佳 ? (我试着写一个非递归函数,但卡住了,因为我们不知道什么是每个文件夹的深度提前)。

如何评价这一功能的表现?它是 OlogN O(N)? (我很困惑,因为没有循环的版本。据我来说,如果有两个循环,我可以把它叫做为O(n ^ 2)

How to evaluate the performance of this function ? Is it OlogN or O(n) ? (I am confused because there is no looping version. According to me, if there is two for loops, i can just call it O(n^2).)

任何意见或指导的?

推荐答案

使用递归来做到这一点的主要问题是:

The main problems with using recursion to do this is:

  1. 如果你的树的深度过大,你可能没有足够的堆栈空间。虽然这将是罕见的有一个文件系统结构的深,它不是不可想象的。

  1. If your tree has a depth that is too large you may not have enough stack space. While it would be uncommon to have that deep of a file system structure, it's not inconceivable.

您使用的不是需要更多的内存,因为你持有到大量的堆栈数据帧,你可能避免的。

You are using more memory than needed, in that you're holding onto a lot of data in stack frames that you could potentially avoid.

对于渐进的复杂性,正在执行一个操作每个节点,不管它的大小,所以它的O(n),其中n为所有节点,而不是在任何深度的节点。

As for the asymptotic complexity, you're performing one operation per node, regardless of it's size, so it's O(n), where n is all nodes, not the nodes at any given depth.

不过,您可以使用内置的方法来遍历整个树处理这一切更有效。这将是比你拿出一个解决方案,更有效的,即使你是非递归的,只需使用:

However, you can handle all of this much more effectively using the built in method to traverse the entire tree. It is going to be more efficient than a solution you'll come up with, even if yours is non-recursive, just use:

foreach(string file in Directory.EnumerateFiles(path, "*", 
    SearchOption.AllDirectories))
{
    System.IO.File.AppendAllText("e:\\personal\\tests.txt",
        System.IO.Path.GetFileName(file) + ":" + rootFolder + "\n")
}

虽然这种解决方案可能是,如果你想知道如何写一个非递归树遍历自己不使用递归,您可以使用一个通用的方法是这样的:

While that solution is likely not to use recursion, if you want to know how to write a non-recursive tree traversal yourself, you can use a general purpose method like this:

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

在你的情况下,调用它可能是这个样子:

In your case calling it could look something like this:

var allFiles = new[] { new DirectoryInfo(path) }
    .Traverse(directory => directory.EnumerateDirectories())
    .Select(directory => directory.EnumerateFiles());

请注意的是,虽然这是细用于遍历不提供一个完整遍历内置的方式一个树,这通常不是理想遍历文件系统。您应该使用,因为它已经被高度优化已经遍历文件系统的特殊情况下,第一个解决方案。

Note that, while this is fine for traversing a tree that doesn't provide a built in way for a full traversal, this is generally not ideal for traversing the file system. You should use the first solution in that it has been highly optimized already for the special case of traversing a file system.

这篇关于文件和文件夹在C#递归上市的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆