Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste artigo, você aprenderá a usar o recurso de curinga (globbing) de arquivo com o pacote NuGet Microsoft.Extensions.FileSystemGlobbing. Um glob é um termo usado para definir padrões de correspondência de nomes de arquivo e diretório com base em curingas. Globbing é o ato de definir um ou mais padrões glob e produzir arquivos com base em 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 objeto Matcher. Um Matcher pode ser instanciado sem parâmetros ou com um parâmetro System.StringComparison, usado internamente para comparar padrões com nomes de arquivo. O Matcher expõe os seguintes métodos aditivos:
Os métodos AddExclude e AddInclude podem ser chamados várias vezes para adicionar vários padrões de nome de arquivo para excluir ou incluir nos resultados. Depois de criar uma instância de Matcher e adicionar padrões, ele será usado para avaliar correspondências de um diretório inicial com o método Matcher.Execute.
Métodos de extensão
O objeto Matcher tem vários métodos de extensão.
Várias exclusões
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 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.
Várias inclusões
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 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ê precisa chamar Matcher.Execute(DirectoryInfoBase) direta ou indiretamente. Para chamar 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 anterior do C#:
- Instancia um objeto Matcher.
- Chama AddIncludePatterns(Matcher, IEnumerable<String>[]) para adicionar vários padrões de nome de arquivo a serem incluídos.
- Declara e atribui o valor do diretório de pesquisa.
- Cria uma instância de DirectoryInfo pelo
searchDirectoryfornecido. - Cria uma instância de DirectoryInfoWrapper pelo
DirectoryInfoencapsulado. - Chama
Executecom a instânciaDirectoryInfoWrapperpara produzir um objeto PatternMatchingResult.
Observação
O tipo DirectoryInfoWrapper é definido no namespace Microsoft.Extensions.FileSystemGlobbing.Abstractions e o tipo DirectoryInfo é definido no namespace System.IO. Para evitar diretivas using desnecessárias, você pode usar os métodos de extensão fornecidos.
Há outro método de extensão que gera uma IEnumerable<string> representando os 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 anterior do C#:
- Instancia um objeto Matcher.
- Chama AddIncludePatterns(Matcher, IEnumerable<String>[]) para adicionar vários padrões de nome de arquivo a serem incluídos.
- Declara e atribui o valor do diretório de pesquisa.
- Chama
GetResultsInFullPathcom o valorsearchDirectorypara produzir todos os arquivos correspondentes comoIEnumerable<string>.
Corresponder sobrecargas
O objeto PatternMatchingResult representa uma coleção de instâncias de FilePatternMatch e expõe um valor boolean que indica se o resultado tem correspondências (PatternMatchingResult.HasMatches).
Com uma instância de Matcher, você pode chamar qualquer uma das várias sobrecargas Match para obter um resultado de correspondência de padrões. Os métodos Match invertem a responsabilidade no chamador para fornecer um arquivo ou uma coleção de arquivos nos quais as correspondências serão avaliadas. Em outras palavras, o chamador é responsável por passar o arquivo para corresponder.
Importante
Ao usar qualquer uma das sobrecargas Match, não há uma E/S do sistema de arquivos envolvida. Toda a globbing de arquivo é feita na memória com os padrões de inclusão e exclusão da instância de matcher. Os parâmetros das sobrecargas Match não precisam ser caminhos totalmente qualificados. O diretório atual (Directory.GetCurrentDirectory()) é usado, quando não especificado.
Para corresponder um único arquivo:
Matcher matcher = new();
matcher.AddInclude("**/*.md");
PatternMatchingResult result = matcher.Match("file.md");
O código anterior do C#:
- Corresponde a qualquer arquivo com a extensão .md, em uma profundidade de diretório arbitrária.
- Se houvesse um arquivo chamado file.md em um subdiretório do diretório atual:
-
result.HasMatchesseriatrue. - e
result.Filesteria uma correspondência.
-
As sobrecargas Match adicionais funcionam de maneiras semelhantes.
Avaliação ordenada de inclusão/exclusão
Por padrão, o correspondente avalia todos os padrões de inclusão primeiro e aplica todos os padrões de exclusão, independentemente da ordem na qual você os adicionou. Isso significa que você não pode re-incluir arquivos que foram excluídos anteriormente.
A partir da versão 10 do 📦 pacote Microsoft.Extensions.FileSystemGlobbing, você pode optar pela avaliação ordenada , em que inclusões e exclusões são processadas exatamente na sequência em que foram adicionadas:
using Microsoft.Extensions.FileSystemGlobbing;
// Preserve the order of patterns when matching.
Matcher matcher = new(preserveFilterOrder: true);
matcher.AddInclude("**/*"); // include everything
matcher.AddExclude("logs/**/*"); // exclude logs
matcher.AddInclude("logs/important/**/*"); // re-include important logs
var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(root)));
foreach (var file in result.Files)
{
Console.WriteLine(file.Path);
}
Nesse modo, os padrões são aplicados um após o outro:
**/*adiciona todos os arquivos.-
logs/**/*elimina tudo delogs/. -
logs/important/**/*adiciona somente arquivos emlogs/important/.
O código existente que usa o construtor padrão continuará executando com o comportamento original de "todas as inclusões e, em seguida, todas as exclusões".
Formatos de padrão
Os padrões especificados nos métodos AddExclude e AddInclude podem usar os formatos a seguir para fazer a correspondência de vários arquivos ou diretórios.
Diretório ou nome do arquivo exato
some-file.txtpath/to/file.txt
Curingas
*em nomes de arquivo e diretório que representem zero para muitos caracteres não incluem caracteres separadores.Valor Descrição *.txtTodos os arquivos com extensão .txt. *.*Todos os arquivos com extensão. *Todos os arquivos no diretório de nível superior. .*Nomes de arquivo começando com “.”. *word*Todos os arquivos com “word” no nome do arquivo. readme.*Todos os arquivos chamados “readme” com qualquer extensão de arquivo. styles/*.cssTodos os arquivos com a 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 cujo nome que é ou começa com “images”. Profundidade arbitrária do diretório (
/**/).Valor Descrição **/*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 corresponder todos os arquivos em um diretório chamado "shared" no nível irmão com o diretório base dado a Matcher.Execute(DirectoryInfoBase), use
../shared/*.
Exemplos
Considere o diretório de exemplo a seguir e cada arquivo na 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
Dica
Algumas extensões de arquivo estão em letras maiúsculas, enquanto outras estão em letras minúsculas. Por padrão, StringComparer.OrdinalIgnoreCase é usado. Para especificar diferentes comportamentos de comparação de cadeia de caracteres, use o construtor Matcher.Matcher(StringComparison).
Para obter todos os arquivos markdown, em que a extensão é .md ou .mtext, independentemente de estar em maiúsculas ou e minúsculas:
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "**/*.md", "**/*.mtext" });
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
Executar o 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 arquivos em um diretório de assets em uma profundidade arbitrária:
Matcher matcher = new();
matcher.AddInclude("**/assets/**/*");
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
Executar o aplicativo produziria resultados semelhantes aos seguintes:
C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg
Para obter arquivos em que o nome do diretório contém a palavra child em uma profundidade arbitrária e as extensões de arquivo não são .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);
}
Executar o 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