2010-04-01 15 views
4

Dans .NET 4, il y a cette méthode Directory.EnumerateFiles() avec récursion qui semble pratique.
Cependant, si une exception se produit dans une récursion, comment puis-je continuer/récupérer à partir de cela et poursuivre l'énumération du reste des fichiers?Existe-t-il un moyen de récupérer à partir d'une exception dans 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); 
} 
+1

Vous pourriez probablement écrire votre propre version en quelques lignes avec récupération d'erreur supplémentaire dont vous avez besoin. – leppie

Répondre

3

J'ai trouvé une solution à cela. En utilisant une pile pour pousser les résultats de l'énumération, on peut effectivement gérer les exceptions. Voici un extrait de code: (inspiré 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

Vous n'avez pas besoin du LINQ qui ne fait rien - remplacez dir de var = de dir dans Directory.EnumerateDirectories ( start, "*. *", SearchOption.TopDirectoryOnly) sélectionnez dir; 'avec' var dirs = Directory.EnumerateDirectories (start, "*. *", SearchOption.TopDirectoryOnly); ' – NetMage

+0

Vous n'avez pas non plus besoin d'utiliser la version' TopDirectoryOnly' - utilisez simplement Directory.EnumerateDirectories (start) '. – NetMage

-2

L'appel à Directory.EnumerateFiles(..) ne mettre en place le recenseur, à cause de-évaluation paresseuse. C'est quand vous l'exécutez, en utilisant un foreach que vous pouvez lever l'exception.

Vous devez donc vous assurer que l'exception est gérée au bon endroit afin que l'énumération puisse continuer.

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

Mise à jour: Il y a quelques informations supplémentaires dans this question

+2

Je ne pense pas que cela fonctionne. le fichier est lié avant le try/catch, et donc l'exception avec être jeté en dehors de votre try/catch. – leppie

0

Je pense que cette approche ne fonctionne pas correctement. Bien que l'exception UnauthorizedAccessException soit interceptée, l'itération s'arrête immédiatement lorsqu'elle se produit. Vous obtenez donc simplement tous les fichiers qui ont été récupérés avant que l'exception ne soit lancée.

+1

Jürgen, c'est exactement ma question. Dans une situation où je veux tous les fichiers, une exception doit être ignorée, donc je peux énumérer tous les fichiers. –

1

J'ai eu le même problème et réimplémenté la fonctionnalité. Vous pouvez trouver la solution au http://rwtools.codeplex.com/. A l'intérieur se trouvent des classes comme "DirectoryEnumerator" et "FileEnumerator" qui ignorent les erreurs, ou (si Sombody aime) lève l'erreur et continuer l'itération.

Espérons que ça aide.

Cordialement, Sandro