代码之家  ›  专栏  ›  技术社区  ›  Magnus Johansson

是否有从directory.enumeratefiles中的异常恢复的方法?

  •  5
  • Magnus Johansson  · 技术社区  · 16 年前

    在.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 回复  |  直到 14 年前
        1
  •  3
  •   Magnus Johansson    15 年前

    我确实找到了解决办法。通过使用堆栈来推送枚举结果,确实可以处理异常。下面是一段代码片段:(灵感来自 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
  •  1
  •   RinderWahn    14 年前

    我也遇到了同样的问题,重新实现了功能。你可以在 http://rwtools.codeplex.com/ .

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

    希望有帮助。

    当做, 桑德罗

        3
  •  0
  •   Jürgen Bayer    16 年前

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

        4
  •  -2
  •   Community Mohan Dere    9 年前

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

    更新 :有一些额外的信息 this question

    推荐文章