訓練
.NET 中的檔案萬用字元
在本文中,您將了解如何搭配 Microsoft.Extensions.FileSystemGlobbing
NuGet 套件使用檔案萬用字元。 glob 是用來根據萬用字元來定義對應檔案和目錄名稱模式的詞彙。 萬用字元是定義一或多個 Glob 模式,並從包含或獨佔相符項目產生檔案的動作。
若要根據使用者定義的模式對應檔案系統中的檔案,請從具現化 Matcher 物件開始。 Matcher
可以具現化沒有參數的 ,或是使用 System.StringComparison 內部用來比較模式與檔案名的參數。 Matcher
會公開下列加法方法:
AddExclude
和 AddInclude
方法都可以呼叫任意次數,以新增各種檔案名模式,以排除或包含結果。 一旦您具現化 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# 程式碼中:
- 具現化 Matcher 物件。
- 若要加入並包含數個檔案名模式請呼叫 AddIncludePatterns(Matcher, IEnumerable<String>[])。
- 宣告並指派搜尋目錄值。
- 從指定的
searchDirectory
具現化 DirectoryInfo。 - 從它包裝的
DirectoryInfo
具現化 DirectoryInfoWrapper。 - 呼叫
Execute
指定的DirectoryInfoWrapper
執行個體來產生 PatternMatchingResult 物件。
注意
此 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
多載的運作方式類似。
AddExclude
和 AddInclude
方法中指定的模式可以使用下列格式來對應多個檔案或目錄。
確切的目錄或檔案名稱
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