有没有办法从 Directory.EnumerateFiles 中的异常中恢复?

发布于 2024-08-27 12:02:52 字数 642 浏览 13 评论 0原文

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

In .NET 4, there's this Directory.EnumerateFiles() method with recursion that seems handy.
However, if an Exception occurs within a recursion, how can I continue/recover from that and continuing enumerate the rest of the files?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情未る 2024-09-03 12:02:52

我确实找到了解决这个问题的方法。通过使用堆栈来压入枚举结果,确实可以处理异常。这是一个代码片段:(灵感来自 这篇文章

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

I did found a solution to this. By using a stack to push the enumeration results, one can indeed handle the exceptions. Here's a code snippet: (inspired by this article)

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);
}
生生漫 2024-09-03 12:02:52

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

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

希望有帮助。

问候,
桑德罗

I had the same problem and re-implemented the functionality. You can find the solution at http://rwtools.codeplex.com/.

Inside are classes like "DirectoryEnumerator" and "FileEnumerator" which ignores errors, or (if sombody likes) throws the error and continue iterating.

Hope it helps.

Regards,
Sandro

我不是你的备胎 2024-09-03 12:02:52

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

I think that this approach does not work correctly. Although the UnauthorizedAccessException is caught, the iteration immediately stops when it occurs. So you just get all files that were retrieved before the exception was thrown.

遥远的绿洲 2024-09-03 12:02:52

由于惰性求值,对 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);
    }
}

更新这个问题

The call to Directory.EnumerateFiles(..) will only set-up the enumerator, because of lazy-evaluation. It's when you execute it, using a foreach that you can raise the exception.

So you need to make sure that the exception is handled at the right place so that the enumeration can continue.

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

Update: There's some extra info in this question

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文