【问题标题】:Recursive looping through files stops abruptly文件的递归循环突然停止
【发布时间】:2012-06-09 22:19:12
【问题描述】:

因此,我尝试遍历硬盘驱动器上的每个文件,但一旦到达第 2115 个(我认为)循环,它就会停止。我相信这是由于我使用递归而导致的堆栈溢出,但我是 C# 新手,真的不知道。这是我的代码,非常感谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;

namespace test_data
{
    class Program
    {
        static string drive = Path.GetPathRoot(Environment.CurrentDirectory);

        static void CrawlDir(string dir)
        {
            string[] dir_package = {};
            List<string> dir_list = new List<string>();
            foreach (string scan_dir in Directory.GetDirectories(dir))
            {

                try
                {
                    dir_list.Add(scan_dir);
                }
                catch (System.Exception error)
                {
                    Console.WriteLine(error.Message);
                }

            }

            dir_package = dir_list.ToArray();
            Process_Package(dir_package);
        }

        static void Main(string[] args)
        {
            CrawlDir(drive);
            Console.ReadLine();
        }

        static void Process_Package(string[] package)
        {
            foreach (string dir in package)
            {
                Console.WriteLine(dir);
                try
                {
                    CrawlDir(dir);
                }
                catch (Exception)
                {
                    Console.WriteLine("Error!");
                }
            }
        }

    }

}

【问题讨论】:

  • 您可能会在尝试访问的子目录之一上收到拒绝访问错误。尝试在 Process_Package 方法中查看 Catch 语句中的异常,以查看实际错误是什么,如果这是发生错误的地方。
  • @Time Schmelter:不,只要 Directory.GetDirectories() 没有返回结果,递归就会停止。

标签: c# recursion stack-overflow callstack


【解决方案1】:

只需使用内置的 - Directory.GetDirectories 支持一个可选参数来指定是否要递归获取所有目录:

var dirs = Directory.GetDirectories(drive, "*.*", SearchOption.AllDirectories);

请注意,这是一个阻塞调用 - 相反,您可以使用 Directory.EnumerateDirectories 在找到目录名称时一一接收:

var dirs = Directory.EnumerateDirectories(drive, "*.*", SearchOption.AllDirectories);
foreach(string dir in dirs)
{
   Console.WriteLine(dir);
}

【讨论】:

    【解决方案2】:

    this overloadSearchOption.AllDirectories 一起使用,这样您就不必进行任何递归:

    public static string[] GetDirectories(
        string path,
        string searchPattern,
        SearchOption searchOption
    )
    

    【讨论】:

      【解决方案3】:

      递归看起来或多或少没问题,尽管您实际上并不需要 CrawlDir 中的列表。如果您有堆栈溢出,您会收到一条讨厌的消息。

      我的猜测是 - 程序完成并在 ReadLine() 处停止等待您按 Enter。

      【讨论】:

        【解决方案4】:

        通过使用列表 (dir_list)、数组 (dir_package) 和两个 try/catch 循环,您为每个递归级别增加了大量开销。我不知道你真正想要做什么,但对于这个例子来说,这太过分了。

        不过,在现代操作系统上导致堆栈溢出需要很多时间。你得到什么错误信息?

        这段代码应该是等价的。

        using System;
        using System.IO;
        
        namespace test_data
        {
            class Program
            {
                static string drive = Path.GetPathRoot(Environment.CurrentDirectory);
        
                static void CrawlDir(string dir)
                {
                    foreach (string subDir in Directory.GetDirectories(dir))
                    {
                        try
                        {
                            Console.WriteLine(subDir);
                            CrawlDir(subDir);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
        
                static void Main(string[] args)
                {
                    CrawlDir(drive);
                    Console.ReadLine();
                }
        
            }
        
        }
        

        【讨论】:

        • 感谢大家的帮助。我只是把它作为一个测试练习。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多