Recursively listing of files and folders in C# [closed]

≡放荡痞女 提交于 2019-12-11 03:26:30

问题


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. I am using recursion. Is this way the best ? (I tried writing a non-recursive function but stuck up because we do not know what is the depth of each folder in advance).

  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).)

Any ideas or guidance's ?


回答1:


The main problems with using recursion to do this is:

  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.

  2. 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.

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.



来源:https://stackoverflow.com/questions/20196395/recursively-listing-of-files-and-folders-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!