2011-03-10 97 views
3

從頂級目錄中獲取與特定正則表達式匹配的文件夾列表的最有效方法是什麼?我目前只是遞歸迭代子文件夾,看它們是否匹配正則表達式,然後如果他們這樣做,我抓住文件名與目錄路徑。C Sharp使用正則表達式搜索文件夾

由於目錄中的文件夾數量衆多,目前此搜索使用當前方法大約需要50分鐘。

private void ProcessFiles(string path, string searchPattern) 
{ 
    string pattern = @"^(\\\\server\\folder1\\subfolder\\(MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3}))))$"; 
    DirectoryInfo di = new DirectoryInfo(path); 
    try 
    { 
     Debug.WriteLine("I'm in " + di.FullName); 
     if (di.Exists) 
     { 
      DirectoryInfo[] dirs = di.GetDirectories("*", SearchOption.TopDirectoryOnly); 
      foreach (DirectoryInfo d in dirs) 
      { 
       string[] splitPath = d.FullName.Split('\\'); 


       var dirMatch = new Regex(pattern, RegexOptions.IgnoreCase); 

       if (dirMatch.IsMatch(d.FullName)) 
       { 
        Debug.WriteLine("---Processing Directory: " + d.FullName + " ---"); 
        FileInfo[] files = d.GetFiles(searchPattern, SearchOption.TopDirectoryOnly); 
        AddColor(files, splitPath); 
       } 
       ProcessFiles(d.FullName, searchPattern); 
      } 
     } 


    } 
    catch (Exception e) 
    { 

    } 

} 
+0

50分鐘意味着你做錯了什麼。發佈您的代碼。 – Jon 2011-03-10 14:41:50

+0

或者:50分鐘意味着他有很多目錄,或者包含的目錄位於映射的UNC路徑或其他慢速設備(如USB棒,DVD驅動器等)上。 – Abel 2011-03-10 14:43:35

+1

@Abel:其中,我只提供UNC場景a似是而非的機會。但無論如何,查看代碼是「調試」這個合理的第一步。 – Jon 2011-03-10 14:47:09

回答

7

我會使用類似下面的,不需要遞歸,讓BCL爲你做的:

// I didn't recount the parenetheses... 
Regex re = new Regex("MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3})))"); 
var dirs = from dir in 
      Directory.EnumerateDirectories(dirPath, "dv_*", 
      SearchOption.AllDirectories) 
      where re.IsMatch(dir) 
      select dir; 

如果它仍然運行50分鐘,你只是一個緩慢的驅動器上,網絡或類似的。

編輯:你編輯你的問題。它清楚地顯示你正在UNC路徑上運行你的代碼。這是非常緩慢的,如果你需要速度,在服務器上運行它本身。

注意:GetDirectories(您使用)和EnumerateDirectories的行爲之間存在很大差異。微軟的文檔says this about it

的EnumerateDirectories和GetDirectories方法的區別如下:當您使用EnumerateDirectories,你可以返回整個集合之前開始枚舉名稱的集合;當您使用GetDirectories時,必須等待返回完整的數組名稱才能訪問該數組。因此,當您處理許多文件和目錄時,EnumerateDirectories可以更高效。

在問候你的問題:它會通過它可以訪問所有的目錄,不要讓它開始你沒有訪問到一個目錄(它會引發異常)。

+0

您的方法如何處理我無權訪問的目錄?它會拋出安全異常還是會跳過該目錄?如果我沒有訪問特定的子目錄,我不希望枚舉中斷。 – Jesse 2011-03-10 15:09:28

+0

@Jess:看我的更新。 – Abel 2011-03-10 15:31:04

+0

太棒了。我會試一試,看看會發生什麼。 – Jesse 2011-03-10 15:54:47

0

要在目錄樹上獲得最快的結果,最好的方法是使用interop。 FindFirstFile,FindNextFile,FindClose是你的朋友。

http://msdn.microsoft.com/en-us/library/aa364418%28v=vs.85%29.aspx

但是,不要指望光的速度,如果你有一個巨大的樹遍歷。

+0

這是一個非常大的遍歷樹,感謝您的輸入。 – Jesse 2011-03-10 14:55:28

0

您可以在子文件夾上遞歸地啓動額外的線程,以嘗試利用您的系統具有的任何並行功能,但可能性大部分開銷可能是磁盤訪問。