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

前端 未结 4 1160
攒了一身酷
攒了一身酷 2020-12-19 12:16

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/recove

相关标签:
4条回答
  • 2020-12-19 12:18

    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

    0 讨论(0)
  • 2020-12-19 12:23

    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);
    }
    
    0 讨论(0)
  • 2020-12-19 12:32

    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.

    0 讨论(0)
  • 2020-12-19 12:32

    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 讨论(0)
提交回复
热议问题