在本文中,了解如何将文件通配与
Microsoft.Extensions.FileSystemGlobbing
NuGet 包一起使用。 glob 是一种术语,用于定义基于通配符匹配文件名和目录名的模式。 通配是定义一个或多个 glob 模式,并从包含或排除的匹配项中生成文件的操作。
若要基于用户定义的模式匹配文件系统中的文件,请通过实例化
Matcher
对象开始。
Matcher
可在没有参数的情况下进行实例化,也可以使用
System.StringComparison
参数进行实例化,该参数在内部用于比较模式和文件名。
Matcher
公开以下附加方法:
Matcher.AddExclude
Matcher.AddInclude
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>[]) 以添加几个要包含的文件名模式。
声明并分配搜索目录值。
从给定的 DirectoryInfo 实例化 searchDirectory
。
从它包装的 DirectoryInfoWrapper 中实例化 DirectoryInfo
。
在给定 DirectoryInfoWrapper
实例的情况下调用 Execute
以生成 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>[]) 以添加几个要包含的文件名模式。
声明并分配搜索目录值。
在给定 searchDirectory
值的情况下调用 GetResultsInFullPath
以将所有匹配文件生成为 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
文件名和目录名中的通配符 *
,表示零到多个字符,不包括分隔符。
相对路径。
若要将同级名为“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) 构造函数。
获取所有文件扩展名为 .md 或 .mtext 的 Markdown 文件(不考虑字符大小写) :
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
在任意深度获取 assets 目录中的任何文件:
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
获取目录名在任意深度包含单词 child 且文件扩展名不是 .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
- 运行时库概述
- 文件和流 I/O