Есть ли способ восстановления после исключения в Directory.EnumerateFiles? - PullRequest
5 голосов
/ 01 апреля 2010

В .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 ]

3 голосов
/ 26 сентября 2010

Я нашел решение для этого. Используя стек для отправки результатов перечисления, можно действительно обрабатывать исключения. Вот фрагмент кода: (по мотивам этой статьи )

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);
}
1 голос
/ 07 октября 2011

У меня была такая же проблема и заново реализована функциональность. Вы можете найти решение на http://rwtools.codeplex.com/.

Внутри находятся классы, такие как "DirectoryEnumerator" и "FileEnumerator", которые игнорируют ошибки или (если кому-то нравится) выдают ошибку и продолжают итерацию.

Надеюсь, это поможет.

С уважением, Сандро

0 голосов
/ 30 мая 2010

Я думаю, что этот подход не работает правильно. Хотя UnauthorizedAccessException перехватывается, итерация немедленно останавливается, когда это происходит. Таким образом, вы просто получаете все файлы, которые были получены до того, как было сгенерировано исключение.

0 голосов
/ 01 апреля 2010

Вызов 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);
    }
}

Обновление : в есть дополнительная информация

...