您没有有效的方法来处理这种情况。如果迭代器本身在尝试获取下一个项目时抛出异常,那么它将无法在此之后为您提供该项目;它不再处于“有效”状态。一旦抛出异常,您就完成了该迭代器。
您唯一的选择是不使用此方法查询整个驱动器。也许您可以编写自己的迭代器来手动遍历驱动器,从而更优雅地跳过无法遍历的项目。
所以,要做这个手动遍历。我们可以从一个Traverse
可以遍历任何树的泛化方法开始(非递归,以更好地有效处理深堆栈):
public static IEnumerable<T> Traverse<T>(
this IEnumerable<T> source
, Func<T, IEnumerable<T>> childrenSelector)
{
var stack = new Stack<T>(source);
while (stack.Any())
{
var next = stack.Pop();
yield return next;
foreach (var child in childrenSelector(next))
stack.Push(child);
}
}
现在我们只需获取根目录,遍历它,并使用一种获取不会抛出异常的子目录的方法:
var root = new DirectoryInfo("C:\\");
var allFiles = new[] { root }.Traverse(dir => GetDirectoriesWithoutThrowing(dir))
.SelectMany(dir => GetFilesWithoutThrowing(dir));
获取子目录的方法可以像这样开始,但可能需要充实:
private static IEnumerable<DirectoryInfo> GetDirectoriesWithoutThrowing(
DirectoryInfo dir)
{
try
{
return dir.GetDirectories();
}
catch (Exception)//if possible catch a more derived exception
{
//TODO consider logging the exception
return Enumerable.Empty<DirectoryInfo>();
}
}
请注意,您可以稍微玩一下这个特定的部分。即使您无法获取其他子目录,您也可以在此处获取一些子目录,您可能需要调整错误处理等。获取文件版本将基本相同,但只是GetFiles
替换。