开发者

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

开发者 https://www.devze.com 2022-12-25 02:40 出处:网络
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 co开发者_运维问答ntinue/recover from that and

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 co开发者_运维问答ntinue/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);
}


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


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


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消