【问题标题】:Scan deep directories recursively递归扫描深层目录
【发布时间】:2012-11-30 00:01:24
【问题描述】:

我正在使用 C# 4.5,并且正在尝试扫描文件共享中的所有文件夹。我想跳过我无法访问的任何文件夹并继续。我所做的是递归地执行它,这会引发 stackoverflow。我明白为什么会这样。所以我的问题是:有什么解决方法吗?

由于我们不能使用递归搜索,您将如何实现这一点?我可以使用任何第三方库来简化此操作吗? GetFolder 函数只是提取一些信息并返回一个自定义类,这很好用。

public void GetFoldersFromFS(string filePath)
{
   if (filePath == null)
   {
      return;
   }

   Directory.SetCurrentDirectory(filePath);
   try
   {
       foreach (var directory in Directory.EnumerateDirectories(Directory.GetCurrentDirectory()))
       {
           Resources.Add(GetFolder(new DirectoryInfo(directory)));
           GetFoldersFromFS(directory);
       }
   }
   catch (UnauthorizedAccessException e)
   {
      Log.Warn(e.Message);
   }
   catch (PathTooLongException e)
   {
      Log.Warn(e.Message);
   }
}

【问题讨论】:

  • Directory.EnumerateDirectories(path, "*.*", SearchOption.AllDirectories ); ??
  • 如果你想通过递归调用实现堆栈溢出,你需要大约 10.000 次迭代。你确定你的目录结构这么深(我觉得windows不支持这么长的路径名)?
  • 是的,就是这么深,这就是为什么我在下山的过程中还要更改目录以避免 PathTooLongException。
  • @L.B:问题是我是否有异常。它只是取消了操作,我一无所有。

标签: c# recursion directory stack-overflow .net-4.5


【解决方案1】:
  1. 为您需要做的目录制作一个列表(待办事项列表)。
  2. 最初,将单个目录(在共享上)添加到待办事项列表中。
  3. 从列表中取出第一个目录并扫描它。
  4. 扫描目录时,将所有子目录添加到待办事项列表(在列表末尾)。
  5. 回到 3 直到待办事项列表为空。

瞧,没有递归的扫描。

伪代码(没有任何 try-catch):

public List<string> ScanDirectory(string directory) {
    var toDoList = new Queue<string>();
    var result = new List<string>();
    toDoList.Enqueue(directory);

    // Keep going while there is anything to do
    while (toDoList.Count > 0) {
        // Get next directory-to-scan, and add it to the result
        var currentDir = toDoList.Dequeue();
        result.Add(currentDir);
        // Get sub directories
        var subDirectories = new DirectoryInfo(currentDir).GetDirectories();    // TODO: Add any other criteria you want to check
        // Add the sub directories to the to-do list
        foreach (var subDirectory in subDirectories) {
            toDoList.Enqueue(subDirectory);
        }
    }

    // Return all found directories
    return result;
}

【讨论】:

  • 如果您保留 List 以返回,您不妨将其用作待办事项队列 - 例如保留当前索引并在超过列表长度时返回。
  • 是的。这只是一个简单的例子。我认为这更好地说明了意图是什么。
  • 它似乎确实有效:) 退出简单的解决方案,现在感觉有点愚蠢。哈哈,还是谢谢。
【解决方案2】:

您可以检查您是否有权通过ACL of the Directory 访问该文件夹,而不是处理异常。

【讨论】:

    【解决方案3】:

    您对 GetFoldersFromFS() 的递归调用是错误的。它不断将同一个文件夹传递给递归调用!

    另外,您不应该调用 Directory.SetCurrentDirectory() 或 GetCurrentDirectory()。

    相反,在您的递归调用中,只需执行:GetFoldersFromFS(directory):

       foreach (var directory in Directory.EnumerateDirectories(filePath))
       {
           Resources.Add(GetFolder(new DirectoryInfo(directory)));
           GetFoldersFromFS(directory);
       }
    

    【讨论】:

    • 确实是错字。
    猜你喜欢
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2014-10-13
    • 2014-09-30
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多