沒有有效的方法來處理這種情況。如果迭代器本身在試圖獲取下一個項目時拋出異常,那麼在此之後它將不能提供該項目;它不再處於「有效」狀態。一旦拋出異常,你就完成了該迭代器。
此處唯一的選擇是不使用此方法查詢整個驅動器。也許你可以編寫自己的迭代器來手動遍歷驅動器,以便無法遍歷的項目被更優雅地跳過。
所以,要做這個手動遍歷。我們可以用廣義含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
。
這可以幫助你,http://msdn.microsoft.com/en-us/library/dd997370.aspx – terrybozzio
無論你做什麼,確保你捕獲特定的異常,而不僅僅是'Exception'。 –
這裏有一個類似的問題http://stackoverflow.com/questions/2559064/is-there-a-way-of-recover-from-an-exception-in-directory-enumeratefiles –