Répertoire.EnumerateFiles => UnauthorizedAccessException
Il y a une bonne nouvelle méthode .NET 4.0 pour récupérer des fichiers dans un répertoire en continu, par l'énumération.
Le problème ici est que si l'on souhaite énumérer tous les fichiers que l'on ne peut savoir à l'avance quels fichiers ou dossiers d'accès sont protégés et peuvent jeter un UnauthorizedAccessException.
À reproduire, on peut simplement exécuter ce fragment:
foreach (var file in Directory.EnumerateFiles(@"c:\", "*", SearchOption.AllDirectories))
{
//whatever
}
Avant cette .Méthode NETTE existé, il a été possible d'atteindre à peu près le même effet par la mise en œuvre de récursive itérateur sur la chaîne de la matrice de retour des méthodes. Mais ce n'est pas tout à fait aussi paresseux que le nouveau .Méthode NETTE.
Alors que faire? Peut le UnauthorizedAccessException être supprimée ou est un fait de la vie lors de l'utilisation de cette méthode?
Me semble que la méthode doit avoir une surcharge d'accepter une action pour traiter toutes les exceptions.
- Oui, votre méthode Dump() doit faire face à des problèmes avec les fichiers qu'il essaie de vidage. Donner une surcharge.
- Ce n'est pas mon problème Hans. Le problème est que foreach-ing sur le fichier itérateur (EnumerateFiles) provoque une UnauthorizedAccessException et qui à son tour s'arrête plus de l'énumération, qui n'est pas souhaitable lorsque l'on veut exhaustive ensemble de résultats.
- Le
Dump()
méthode n'est pas le problème ici, c'est juste des promenades à travers la chaîne de l'énumération. Le problème est leDirectory.EnumerateFiles
méthode elle-même. Et je ne pense pas qu'il y est un moyen de gérer le problème. Vous devez recourir àSearchOption.TopDirectoryOnly
et de gérer la récursivité vous-même, je crois. - Il y a une simple solution de contournement. Elle suce bien...
- Ce (et pour d'autres raisons) est pourquoi j'ai finalement fini par écrire un wrapper pour NtQueryDirectoryFile moi-même.
- Je me demandais si vous pouviez poster une réponse?
- Je peux, mais il faut vérifier en premier. Pas convaincu que cela sera effectivement le travail.
- J'ai posté une solution à ce stackoverflow.com/questions/13130052/.... La solution que j'ai posté se comporte comme un vrai IEnumerable dans le sens qu'il ne fonctionne si il ya du travail qui lui est demandé.
Vous devez vous connecter pour publier un commentaire.
Ths question avec la réponse ci-dessus est qu'elle ne fait pas prendre soin d'exception dans les sous répertoires. Ce serait une meilleure façon de gérer les exceptions de sorte que vous obtenez TOUS les fichiers de TOUS les sous-répertoires à l'exception de ceux ayant jeté un accès exception:
Je ne Pouvais pas la ci-dessus pour travailler, mais c'est mon œuvre, je l'ai testé sur c:\users sur un "Win7" boîte", parce que si toutes ces "méchants" dirs:
Classe:
Je comprends que c'est
MoveNext
qui lève l'exception.J'ai essayé d'écrire une méthode sûre pour des marches d'une séquence et tente d'ignorer
MoveNext
exceptions. Cependant, je ne suis pas sûr siMoveNext
progrès de la position quand elle lève une exception, donc cela pourrait aussi bien être une boucle infinie. C'est aussi une mauvaise idée, parce que nous nous appuyons sur les détails d'implémentation.Mais c'est juste tellement amusant!
Cela ne fonctionnera que si les conditions suivantes sont vraies à propos du cadre de mise en œuvre de cet itérateur (voir
FileSystemEnumerableIterator<TSource>
Réflecteur de référence):MoveNext
progrès de sa position lorsqu'il échoue;MoveNext
échoue sur le dernier élément, les appels suivants seront de retourfalse
au lieu de lancer une exception;Même si elle travaille, s'il vous plaît, ne l'utilisez jamais dans de production!
Mais je me demande vraiment si il n'.
Je suis en retard, mais je vous suggère d'utiliser motif observable à la place:
Basé sur strudso réponse, mais que les méthodes d'extension pour les deux
FileInfo
etDirectoryInfo
.retval
deux fois, une fois pourConcat
et une autre fois pourSelectMany
.