使用LINQ取得目錄下符合規則並排除特定檔案之檔案清單

  • 4906
  • 0
  • 2013-09-11

使用LINQ取得目錄下符合規則並排除特定檔案之檔案清單

DotBlogs Tags: , ,

以下程式使用 LINQPad 的 C# Program 模式執行。

先看 Code,再來說明重點的部分:


void Main()
{
    string[] files = GetDirectoryFiles(@"d:\MyDocs\Visual Studio 2008\Projects\");
    files.Dump();
}

string[] GetDirectoryFiles(string path)
{
    string[] files = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
                     .Where (f => { string ext = Path.GetExtension(f).ToLower();
                                     if (".vb".Equals(ext) || ".aspx".Equals(ext) ||
                                        ".ascx".Equals(ext) || ".asmx".Equals(ext) ||
                                        ".vbproj".Equals(ext) )
                                    {
                                        string filename = Path.GetFileName(f).ToLower();
                                        if ("assemblyinfo.vb".Equals(filename) || "global.asax".Equals(filename) ||
                                            "application.designer.vb".Equals(filename) || "resources.designer.vb".Equals(filename) || 
                                            "settings.designer.vb".Equals(filename) || "mywebextension.vb".Equals(filename) || 
                                            "global.asax.vb".Equals(filename) )
                                        {
                                            return false;
                                        }
                                        return true;
                                    }
                                     return false;})
                     .OrderBy (f => Path.GetExtension(f).ToLower())
                     .ToArray();
    return files;
}

輸出結果部分截圖:

135647

程式碼重點說明:

  • Directory.EnumerateFiles :在 .Net 3.5(含) 以前,取得指定目錄下的檔案通常使用 Directory.GetFiles(),不過從 .Net 4.0 開始,若目錄下有大量檔案和子目錄時,建議改用 Direcotry.EnumerateFiles() 方法,效能較佳(官方說法,註1)。請參閱:Directory.EnumerateFiles 方法 (String, String, SearchOption)
  • 其實 EnumerateFiles 可以下 searchPattern 參數(第二個參數),但是它只能指定一個規則,我的案例中,想要符合多個條件,還要排除特定檔案,所以不合用,因此只放了星號表示目錄下檔案我全要了。
  • Where 條件中,先取得檔案的副檔名並轉小寫(Path.GetExtension(f).ToLower()),然後比對要篩選出來的副檔案。
  • 承續上述 Where 條件,再取得檔案的完整名稱並轉小寫(Path.GetFileName(f).ToLower()),用以排除不要的檔案。其實在 String.Equals() 的方法裡,可以指定 StringComparison 參數,設定不分大小寫,不過我不想讓判斷式變的好長好醜,所以才先轉小寫,並都以小寫的字串來做 Equals() 的判斷。此純為個人習慣。

註1:Leo 實測搜尋 STATII 硬碟上,10GB(111,385 個檔案,10,257 個資料夾)的資料夾,不放任何篩選條件,EnumerateFiles 和 GetFiles 差別不到 0.1 秒,所以我只能說官方說法是 EnumerateFiles 比較快。

--------
沒什麼特別的~
不過是一些筆記而已