Utiliser des caractères génériques dans les fichiers dans .NET
Dans cet article, vous allez apprendre à utiliser des caractères génériques (« globbing ») dans les fichiers avec le package NuGet Microsoft.Extensions.FileSystemGlobbing
. Un glob est un terme utilisé afin de définir des modèles pour la mise en correspondance des noms de fichiers et de répertoires sur la base des caractères génériques. Le « globbing » correspond à la définition d’un ou plusieurs modèles Glob et à la restitution de fichiers à partir de correspondances inclusives ou exclusives.
Modèles
Pour faire correspondre des fichiers dans le système de fichiers en fonction des modèles définis par l’utilisateur, commencez par instancier un objet Matcher. Un Matcher
peut être instancié sans paramètres ou avec un paramètre System.StringComparison, qui est utilisé en interne pour comparer les modèles aux noms de fichiers. Le Matcher
expose les méthodes additives suivantes :
Les méthodes AddExclude
et AddInclude
peuvent être appelées n’importe quel nombre de fois, afin d’ajouter différents modèles de nom de fichier à exclure ou à inclure dans les résultats. Une fois que vous avez instancié un Matcher
et ajouté des modèles, il est ensuite utilisé pour évaluer les correspondances à partir d’un répertoire de départ avec la méthode Matcher.Execute.
Méthodes d’extension
L’objet Matcher
a plusieurs méthodes d’extension.
Exclusions multiples
Pour ajouter plusieurs modèles d’exclusion, vous pouvez utiliser :
Matcher matcher = new();
matcher.AddExclude("*.txt");
matcher.AddExclude("*.asciidoc");
matcher.AddExclude("*.md");
Vous pouvez également utiliser MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) pour ajouter plusieurs modèles d’exclusion dans un seul appel :
Matcher matcher = new();
matcher.AddExcludePatterns(new [] { "*.txt", "*.asciidoc", "*.md" });
Cette méthode d’extension itère sur tous les modèles fournis appelant AddExclude en votre nom.
Inclusions multiples
Pour ajouter plusieurs modèles d’inclusion, vous pouvez utiliser :
Matcher matcher = new();
matcher.AddInclude("*.txt");
matcher.AddInclude("*.asciidoc");
matcher.AddInclude("*.md");
Vous pouvez également utiliser MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) pour ajouter plusieurs modèles d’inclusion dans un seul appel :
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });
Cette méthode d’extension itère sur tous les modèles fournis appelant AddInclude en votre nom.
Obtenir tous les fichiers correspondants
Pour obtenir tous les fichiers correspondants, vous devez appeler Matcher.Execute(DirectoryInfoBase) directement ou indirectement. Pour l’appeler directement, vous avez besoin d’un répertoire de recherche :
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.
Le code C# précédent :
- Instancie un objet Matcher.
- Appelle AddIncludePatterns(Matcher, IEnumerable<String>[]) pour ajouter plusieurs modèles de nom de fichier à inclure.
- Déclare et affecte la valeur du répertoire de recherche.
- Instancie un élément DirectoryInfo à partir de l’élément
searchDirectory
donné. - Instancie un élément DirectoryInfoWrapper à partir de l’élément
DirectoryInfo
qu’il inclut dans un wrapper. - Appelle
Execute
sur la base de l’instanceDirectoryInfoWrapper
pour générer un objet PatternMatchingResult.
Notes
Le type DirectoryInfoWrapper
est défini dans l’espace de noms Microsoft.Extensions.FileSystemGlobbing.Abstractions
et le type DirectoryInfo
est défini dans l’espace de noms System.IO
. Pour éviter des directives using
inutiles, vous pouvez utiliser les méthodes d’extension fournies.
Il existe une autre méthode d’extension qui génère un élément IEnumerable<string>
représentant les fichiers correspondants :
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.
Le code C# précédent :
- Instancie un objet Matcher.
- Appelle AddIncludePatterns(Matcher, IEnumerable<String>[]) pour ajouter plusieurs modèles de nom de fichier à inclure.
- Déclare et affecte la valeur du répertoire de recherche.
- Appelle
GetResultsInFullPath
sur la base de la valeursearchDirectory
pour générer tous les fichiers correspondants en tant queIEnumerable<string>
.
Surchage de correspondances
L’objet PatternMatchingResult représente une collection d’instances FilePatternMatch et expose une valeur boolean
indiquant si le résultat a des correspondances : PatternMatchingResult.HasMatches.
Avec une instance Matcher
, vous pouvez appeler l’une des différentes surcharges Match
pour obtenir un résultat de critères spéciaux. Les méthodes Match
inversent la responsabilité de l’appelant pour fournir un fichier ou une collection de fichiers dans lesquels évaluer les correspondances. En d’autres termes, l’appelant est chargé de transmettre le fichier à mettre en correspondance.
Important
Lorsque vous utilisez l’une des surcharges Match
, cela n’implique aucune E/S de système de fichiers. L’ensemble du globbing de fichier est effectué en mémoire avec les modèles d’inclusion et d’exclusion de l’instance matcher
. Les paramètres des surcharges Match
n’ont pas besoin d’être des chemins d’accès complets. Le répertoire actif (Directory.GetCurrentDirectory()) est utilisé en l’absence de spécification.
Pour faire correspondre un seul fichier :
Matcher matcher = new();
matcher.AddInclude("**/*.md");
PatternMatchingResult result = matcher.Match("file.md");
Le code C# précédent :
- Fait correspondre n’importe quel fichier avec l’extension de fichier .md, à une profondeur de répertoire arbitraire.
- Si un fichier nommé file.md existe dans un sous-répertoire du répertoire actif :
result.HasMatches
aurait la valeurtrue
.- Et
result.Files
aurait une correspondance.
Les surcharges Match
supplémentaires fonctionnent de manière similaire.
Formats de modèle
Les modèles spécifiés dans les méthodes AddExclude
et AddInclude
peuvent utiliser les formats suivants pour faire à plusieurs fichiers ou répertoires.
Répertoire ou nom de fichier exact
some-file.txt
path/to/file.txt
Caractères génériques
*
dans les noms de fichiers et de répertoires qui représentent zéro à plusieurs caractères, sans inclure de caractères de séparation.Valeur Description *.txt
Tous les fichiers avec l’extension de fichier .txt. *.*
Tous les fichiers avec une extension. *
Tous les fichiers dans le répertoire de niveau supérieur. .*
Noms de fichiers commençant par « . ». *word*
Tous les fichiers dont le nom inclut « word ». readme.*
Tous les fichiers nommés « readme » avec n’importe quelle extension de fichier. styles/*.css
Tous les fichiers avec l’extension .css dans le répertoire « styles/ ». scripts/*/*
Tous les fichiers dans « scripts/ » ou un niveau de sous-répertoire sous « scripts/ ». images*/*
Tous les fichiers d’un dossier dont le nom est ou commence par « images ». Profondeur de répertoire arbitraire (
/**/
).Valeur Description **/*
Tous les fichiers d’un sous-répertoire. dir/
Tous les fichiers d’un sous-répertoire sous « dir/ ». dir/**/*
Tous les fichiers d’un sous-répertoire sous « dir/ ». Chemins relatifs.
Pour faire correspondre tous les fichiers d’un répertoire nommé « shared » au niveau frère du répertoire de base donné à Matcher.Execute(DirectoryInfoBase), utilisez
../shared/*
.
Exemples
Intéressons-nous à l’exemple de répertoire suivant et à chaque fichier dans son dossier correspondant.
📁 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
Conseil
Certaines extensions de fichier sont en majuscules, tandis que d’autres sont en minuscules. Par défaut, StringComparer.OrdinalIgnoreCase est utilisé. Pour spécifier différents comportements de comparaison de chaînes, utilisez le constructeur Matcher.Matcher(StringComparison).
Pour obtenir tous les fichiers Markdown, où l’extension de fichier est .md ou .mtext, quel que soit la casse de caractère :
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "**/*.md", "**/*.mtext" });
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
L’exécution de l’application génère des résultats similaires à ce qui suit :
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
Pour obtenir tous les fichiers d’un répertoire assets à une profondeur arbitraire :
Matcher matcher = new();
matcher.AddInclude("**/assets/**/*");
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
L’exécution de l’application génère des résultats similaires à ce qui suit :
C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg
Pour obtenir les fichiers où le nom de répertoire contient le mot child à une profondeur arbitraire, et où les extensions de fichier ne sont pas .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);
}
L’exécution de l’application génère des résultats similaires à ce qui suit :
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