5

在 .NET 4 中,有一个带有递归的Directory.EnumerateFiles()方法,看起来很方便。
但是,如果在递归中发生异常,我如何继续/从中恢复并继续枚举其余文件?

try
{
  var files = from file in Directory.EnumerateFiles("c:\\",
                           "*.*", SearchOption.AllDirectories)
              select new
              {
                File = file
              };

  Console.WriteLine(files.Count().ToString());

}
catch (UnauthorizedAccessException uEx)
{
  Console.WriteLine(uEx.Message);
}
catch (PathTooLongException ptlEx)
{
  Console.WriteLine(ptlEx.Message);
}
4

4 回答 4

3

我确实找到了解决方案。通过使用堆栈来推送枚举结果,确实可以处理异常。这是一个代码片段:(受本文启发)

List<string> results = new List<string>();
string start = "c:\\";
results.Add(start);
Stack<string> stack = new Stack<string>();

do
{
  try
  {
    var dirs = from dir in Directory.EnumerateDirectories(
                     start, "*.*", SearchOption.TopDirectoryOnly)
                select dir;

    Array.ForEach(dirs.ToArray(), stack.Push);
    start = stack.Pop();
    results.Add(start);
  }
  catch (UnauthorizedAccessException ex)
  {
    Console.WriteLine(ex.Message);
    start = stack.Pop();
    results.Add(start);
  }

} while (stack.Count != 0);

foreach (string file in results)
{
  Console.WriteLine(file);
}
于 2010-09-25T21:16:20.203 回答
1

我遇到了同样的问题并重新实现了该功能。您可以在http://rwtools.codeplex.com/找到解决方案。

里面有像“DirectoryEnumerator”和“FileEnumerator”这样的类,它们忽略错误,或者(如果sombody喜欢)抛出错误并继续迭代。

希望能帮助到你。

问候, 桑德罗

于 2011-10-07T18:36:14.940 回答
0

我认为这种方法不能正常工作。尽管捕获了 UnauthorizedAccessException,但迭代在发生时会立即停止。因此,您只需获取在引发异常之前检索到的所有文件。

于 2010-05-30T09:28:09.803 回答
-2

由于惰性评估,调用Directory.EnumerateFiles(..)只会设置枚举器。当你执行它时,使用foreach你可以引发异常。

因此,您需要确保在正确的位置处理异常,以便枚举可以继续。

var files = from file in Directory.EnumerateFiles("c:\\",
                           "*.*", SearchOption.AllDirectories)
              select new
              {
                File = file
              };

foreach (var file in files)
{
    try
    {          
        Console.Writeline(file);
    }
    catch (UnauthorizedAccessException uEx)
    {
        Console.WriteLine(uEx.Message);
    }
    catch (PathTooLongException ptlEx)
    {
        Console.WriteLine(ptlEx.Message);
    }
}

更新:这个问题中有一些额外的信息

于 2010-04-01T10:06:35.107 回答