.NET 中的檔案萬用字元

在本文中,您將了解如何搭配 Microsoft.Extensions.FileSystemGlobbing NuGet 套件使用檔案萬用字元。 glob 是用來根據萬用字元來定義對應檔案和目錄名稱模式的詞彙。 萬用字元是定義一或多個 Glob 模式,並從包含或獨佔相符項目產生檔案的動作。

模式

若要根據使用者定義的模式對應檔案系統中的檔案,請從具現化 Matcher 物件開始。 Matcher 可以具現化沒有參數的 ,或是使用 System.StringComparison 內部用來比較模式與檔案名的參數。 Matcher 會公開下列加法方法:

AddExcludeAddInclude 方法都可以呼叫任意次數,以新增各種檔案名模式,以排除或包含結果。 一旦您具現化 Matcher 並新增模式之後,就會使用 Matcher.Execute 方法,從起始目錄評估相符項目。

擴充方法

Matcher 物件有數個擴充方法。

多個排除項目

若要新增多個排除模式,您可以使用:

Matcher matcher = new();
matcher.AddExclude("*.txt");
matcher.AddExclude("*.asciidoc");
matcher.AddExclude("*.md");

或者,您可以使用 MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) 在單一呼叫中新增多個排除模式:

Matcher matcher = new();
matcher.AddExcludePatterns(new [] { "*.txt", "*.asciidoc", "*.md" });

此擴充方法會逐一查看代表您呼叫 AddExclude 的所有提供模式。

多個包含項目

若要新增多個包含模式,您可以使用:

Matcher matcher = new();
matcher.AddInclude("*.txt");
matcher.AddInclude("*.asciidoc");
matcher.AddInclude("*.md");

或者,您可以使用 MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) 在單一呼叫中新增多個包含模式:

Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });

此擴充方法會逐一查看代表您呼叫 AddInclude 的所有提供模式。

取得所有相符的檔案

若要取得所有相符的檔案,您必須直接或間接呼叫 Matcher.Execute(DirectoryInfoBase)。 若要直接呼叫,您需要搜尋目錄:

Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });

string searchDirectory = "../starting-folder/";

PatternMatchingResult result = matcher.Execute(
    new DirectoryInfoWrapper(
        new DirectoryInfo(searchDirectory)));

// Use result.HasMatches and results.Files.
// The files in the results object are file paths relative to the search directory.

在上述 C# 程式碼中:

注意

DirectoryInfoWrapper 型別定義於 Microsoft.Extensions.FileSystemGlobbing.Abstractions 命名空間中,且 DirectoryInfo 型別定義於 System.IO 命名空間中。 若要避免不必要的 using 陳述式,您可以使用提供的擴充方法。

有另一個擴充方法會產生 IEnumerable<string>,代表相符的檔案:

Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });

string searchDirectory = "../starting-folder/";

IEnumerable<string> matchingFiles = matcher.GetResultsInFullPath(searchDirectory);

// Use matchingFiles if there are any found.
// The files in this collection are fully qualified file system paths.

在上述 C# 程式碼中:

  • 具現化 Matcher 物件。
  • 若要加入並包含數個檔案名模式請呼叫 AddIncludePatterns(Matcher, IEnumerable<String>[])
  • 宣告並指派搜尋目錄值。
  • 呼叫 GetResultsInFullPath 指定的 searchDirectory 值來產生作為 IEnumerable<string> 的所有相符檔案。

對應多載

PatternMatchingResult 物件代表 FilePatternMatch 執行個體的集合,並公開 boolean 值,指出結果是否與 PatternMatchingResult.HasMatches 相符。

使用 Matcher 執行個體時,您可以呼叫任何各種 Match 多載,以取得模式對應結果。 Match 方法會反轉呼叫端的責任,以提供要評估相符項目的檔案或檔案集合。 換句話說,呼叫端應負責傳遞要進行對應的檔案。

重要

使用任何 Match 多載時,不會涉及檔案系統 I/O。 所有檔案萬用字元都會在記憶體中完成,其中包含和排除 matcher 執行個體的模式。 Match 多載的參數不一定是完整路徑。 未指定時會使用目前目錄 (Directory.GetCurrentDirectory())。

若要對應單一檔案:

Matcher matcher = new();
matcher.AddInclude("**/*.md");

PatternMatchingResult result = matcher.Match("file.md");

在上述 C# 程式碼中:

  • 於任意目錄深度對應任何副檔名為 .md 的檔案。
  • 如果名為 file.md 的檔案存在於目前目錄中的子目錄中:
    • result.HasMatches 會是 true
    • result.Files 會有一個相符項目。

其他 Match 多載的運作方式類似。

模式格式

AddExcludeAddInclude 方法中指定的模式可以使用下列格式來對應多個檔案或目錄。

  • 確切的目錄或檔案名稱

    • some-file.txt
    • path/to/file.txt
  • 檔案和目錄名稱中的萬用字元 *,代表零到許多字元,不包括分隔符號。

    Description
    *.txt 具有 .txt 副檔名的所有檔案。
    *.* 具有副檔名的所有檔案。
    * 最上層目錄中的所有檔案。
    .* 以 '.' 開頭的檔案名稱。
    *word* 檔案名稱中有 'word' 的所有檔案。
    readme.* 具有任何副檔名所有名為 'readme' 的檔案。
    styles/*.css 目錄 'style/' 中具有 '.css' 副檔名的所有檔案。
    scripts/*/* 'scripts/' 中的所有檔案,或 'scripts/' 下的一個子目錄層級。
    images*/* 資料夾名稱為或開頭為 'images' 其中的所有檔案。
  • 任意目錄深度 (/**/)。

    Description
    **/* 任何子目錄中的所有檔案。
    dir/ 'dir/' 下任何子目錄中的所有檔案。
    dir/**/* 'dir/' 下任何子目錄中的所有檔案。
  • 相對路徑。

    若要對應同層級目錄中名為「shared」的所有檔案,與提供給 Matcher.Execute(DirectoryInfoBase) 的基底目錄相符,請使用 ../shared/*

範例

請考慮下列範例目錄,以及其對應資料夾中的每個檔案。

📁 parent
│    file.md
│    README.md
│
└───📁 child
    │    file.MD
    │    index.js
    │    more.md
    │    sample.mtext
    │
    ├───📁 assets
    │        image.png
    │        image.svg
    │
    └───📁 grandchild
             file.md
             style.css
             sub.text

提示

有些副檔名為大寫,而其他副檔名則為小寫。 預設會使用 StringComparer.OrdinalIgnoreCase。 若要指定不同的字串比較行為,請使用 Matcher.Matcher(StringComparison) 建構函式。

若要取得所有 Markdown 檔案,其中不論字元大小寫,副檔名為 .md.mtext

Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "**/*.md", "**/*.mtext" });

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

執行應用程式會輸出類似下列的結果:

C:\app\parent\file.md
C:\app\parent\README.md
C:\app\parent\child\file.MD
C:\app\parent\child\more.md
C:\app\parent\child\sample.mtext
C:\app\parent\child\grandchild\file.md

若要在任意深度取得資產目錄中的任何檔案:

Matcher matcher = new();
matcher.AddInclude("**/assets/**/*");

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

執行應用程式會輸出類似下列的結果:

C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg

若要取得目錄名稱包含任意深度子項目的任何檔案,且副檔名不是 .md.text.mtext

Matcher matcher = new();
matcher.AddInclude("**/*child/**/*");
matcher.AddExcludePatterns(
    new[]
    {
        "**/*.md", "**/*.text", "**/*.mtext"
    });

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

執行應用程式會輸出類似下列的結果:

C:\app\parent\child\index.js
C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg
C:\app\parent\child\grandchild\style.css

另請參閱