Is there a way of recover from an Exception in Directory.EnumerateFiles?

荒凉一梦 提交于 2019-11-28 04:28:57

问题


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

回答1:


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



回答2:


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




回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/2559064/is-there-a-way-of-recover-from-an-exception-in-directory-enumeratefiles

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