2010-04-01 46 views
4

在.NET 4中,有這種Directory.EnumerateFiles()方法,遞歸似乎很方便。
但是,如果在遞歸中發生異常,我該如何繼續/恢復並繼續枚舉其餘文件?是否有從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

你也許可以用額外的錯誤恢復,你需要幾行寫你自己的版本。 – leppie 2010-04-01 10:21:32

回答

3

我確實找到了解決方案。通過使用堆棧來推送枚舉結果,可以確實處理異常。這裏有一個代碼片段:(由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

你不需要不執行任何操作的LINQ - 在Directory.EnumerateDirectories中替換'var dirs = from dir'( start,「*。*」,SearchOption.TopDirectoryOnly) select dir;'用'var dirs = Directory.EnumerateDirectories (start,「*。*」,SearchOption.TopDirectoryOnly);' – NetMage 2017-10-20 22:57:08

+0

您也不需要使用'TopDirectoryOnly'版本 - 只需使用'Directory.EnumerateDirectories(start)'。 – NetMage 2017-10-21 00:22:34

-2

由於延遲評估,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); 
    } 
} 

更新:有一個在this question

+2

我不認爲這有效。文件被綁定在try/catch之前,因此異常被拋出try/catch之外。 – leppie 2010-04-01 10:20:43

0

我認爲這種方法並不能正常工作,一些額外的信息。儘管捕獲了UnauthorizedAccessException,但迭代立即停止。因此,您只需獲取在引發異常之前檢索的所有文件。

+1

尤爾根,那正是我的問題。在我想要所有文件的情況下,Exception應該被忽略,所以我可以枚舉所有文件。 – 2010-05-30 11:01:21

1

我有同樣的問題,並重新實現的功能。您可以在http://rwtools.codeplex.com/找到解決方案。

裏面有像「DirectoryEnumerator」和「FileEnumerator」這樣的類,它忽略錯誤,或者(如果sombody喜歡)拋出錯誤並繼續迭代。

希望它有幫助。

問候, 桑德羅

相關問題