Partilhar via


Globbing de arquivo no .NET

Neste artigo, você aprenderá a usar o globbing de arquivos com o Microsoft.Extensions.FileSystemGlobbing pacote NuGet. Um glob é um termo usado para definir padrões para nomes de arquivos e diretórios correspondentes com base em curingas. Globbing é o ato de definir um ou mais padrões de glob e produzir arquivos de correspondências inclusivas ou exclusivas.

Padrões

Para corresponder arquivos no sistema de arquivos com base em padrões definidos pelo usuário, comece instanciando um Matcher objeto. A Matcher pode ser instanciado sem parâmetros, ou com um System.StringComparison parâmetro, que é usado internamente para comparar padrões com nomes de arquivos. O Matcher expõe os seguintes métodos aditivos:

Ambos os AddExclude métodos podem AddInclude ser chamados qualquer número de vezes, para adicionar vários padrões de nome de arquivo para excluir ou incluir dos resultados. Depois de instanciar um Matcher e adicionar padrões, ele é usado para avaliar correspondências de um diretório inicial com o Matcher.Execute método.

Métodos de extensão

O Matcher objeto tem vários métodos de extensão.

Exclusões múltiplas

Para adicionar vários padrões de exclusão, você pode usar:

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

Como alternativa, você pode usar o MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) para adicionar vários padrões de exclusão em uma única chamada:

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

Esse método de extensão itera em todos os padrões fornecidos chamando AddExclude em seu nome.

Inclusões múltiplas

Para adicionar vários padrões de inclusão, você pode usar:

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

Como alternativa, você pode usar o MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) para adicionar vários padrões de inclusão em uma única chamada:

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

Esse método de extensão itera em todos os padrões fornecidos chamando AddInclude em seu nome.

Obter todos os arquivos correspondentes

Para obter todos os arquivos correspondentes, você tem que ligar Matcher.Execute(DirectoryInfoBase) direta ou indiretamente. Para chamá-lo diretamente, você precisa de um diretório de pesquisa:

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.

O código C# anterior:

Nota

O DirectoryInfoWrapper tipo é definido no Microsoft.Extensions.FileSystemGlobbing.Abstractions namespace e o DirectoryInfo tipo é definido no System.IO namespace. Para evitar diretivas desnecessárias using , você pode usar os métodos de extensão fornecidos.

Há outro método de extensão que produz uma IEnumerable<string> representação dos arquivos correspondentes:

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.

O código C# anterior:

  • Instancia um Matcher objeto.
  • Chamadas AddIncludePatterns(Matcher, IEnumerable<String>[]) para adicionar vários padrões de nome de arquivo para incluir.
  • Declara e atribui o valor do diretório de pesquisa.
  • Chamadas GetResultsInFullPath dado o searchDirectory valor para produzir todos os arquivos correspondentes como um IEnumerable<string>arquivo .

Sobrecargas de correspondência

O PatternMatchingResult objeto representa uma coleção de FilePatternMatch instâncias e expõe um boolean valor que indica se o resultado tem correspondências—PatternMatchingResult.HasMatches.

Com uma instância, você pode chamar qualquer uma Matcher das várias Match sobrecargas para obter um resultado de correspondência de padrão. Os Match métodos invertem a responsabilidade do chamador de fornecer um arquivo ou uma coleção de arquivos para avaliar as correspondências. Em outras palavras, o chamador é responsável por passar o arquivo para corresponder.

Importante

Ao usar qualquer uma das sobrecargas, não há E/S do sistema de Match arquivos envolvida. Todo o globbing de arquivo é feito na memória com os padrões include e exclude da matcher instância. Os parâmetros das Match sobrecargas não precisam ser caminhos totalmente qualificados. O diretório atual (Directory.GetCurrentDirectory()) é usado quando não especificado.

Para corresponder a um único ficheiro:

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

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

O código C# anterior:

  • Corresponde a qualquer arquivo com a extensão de arquivo .md , em uma profundidade de diretório arbitrária.
  • Se existir um arquivo chamado file.md em um subdiretório do diretório atual:
    • result.HasMatches seria true.
    • e result.Files teria uma partida.

As sobrecargas adicionais Match funcionam de forma semelhante.

Formatos de padrão

Os padrões especificados nos AddExclude métodos e AddInclude podem usar os seguintes formatos para corresponder a vários arquivos ou diretórios.

  • Diretório exato ou nome do arquivo

    • some-file.txt
    • path/to/file.txt
  • Curingas * em nomes de arquivos e diretórios que representam zero a muitos caracteres, não incluindo caracteres separadores.

    valor Description
    *.txt Todos os arquivos com extensão de arquivo .txt .
    *.* Todos os ficheiros com uma extensão.
    * Todos os arquivos no diretório de nível superior.
    .* Nomes de ficheiros que comecem por '.'.
    *word* Todos os ficheiros com 'word' no nome do ficheiro.
    readme.* Todos os arquivos chamados 'readme' com qualquer extensão de arquivo.
    styles/*.css Todos os arquivos com extensão '.css' no diretório 'styles/'.
    scripts/*/* Todos os arquivos em 'scripts/' ou um nível de subdiretório em 'scripts/'.
    images*/* Todos os arquivos em uma pasta com nome que é ou começa com 'imagens'.
  • Profundidade de diretório arbitrária (/**/).

    valor Description
    **/* Todos os arquivos em qualquer subdiretório.
    dir/ Todos os arquivos em qualquer subdiretório em 'dir/'.
    dir/**/* Todos os arquivos em qualquer subdiretório em 'dir/'.
  • Caminhos relativos.

    Para fazer a correspondência entre todos os arquivos em um diretório chamado "compartilhado" no nível irmão e o diretório base fornecido ao Matcher.Execute(DirectoryInfoBase), use ../shared/*.

Exemplos

Considere o seguinte diretório de exemplo e cada arquivo dentro de sua pasta correspondente.

📁 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

Gorjeta

Algumas extensões de arquivo estão em maiúsculas, enquanto outras estão em minúsculas. Por padrão, StringComparer.OrdinalIgnoreCase é usado. Para especificar um comportamento de comparação de cadeia de caracteres diferente, use o Matcher.Matcher(StringComparison) construtor.

Para obter todos os arquivos de markdown, onde a extensão do arquivo é .md ou .mtext, independentemente do caso do caractere:

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

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

A execução do aplicativo produziria resultados semelhantes aos seguintes:

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

Para obter quaisquer arquivos em um diretório de ativos em uma profundidade arbitrária:

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

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

A execução do aplicativo produziria resultados semelhantes aos seguintes:

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

Para obter quaisquer arquivos em que o nome do diretório contenha a palavra filho em uma profundidade arbitrária e as extensões de arquivo não sejam .md, .text ou .mtext:

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

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

A execução do aplicativo produziria resultados semelhantes aos seguintes:

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

Consulte também