在本文中,了解如何将文件通配与 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 重载的工作方式类似。

      AddExcludeAddInclude 方法中指定的模式可使用以下格式来匹配多个文件或目录。

    • 确切的目录名或文件名

    • 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
  •