Verwenden von Dateiplatzhaltern in .NET

In diesem Artikel erfahren Sie, wie Sie Dateiplatzhalter (File Globbing) mit dem Microsoft.Extensions.FileSystemGlobbing-NuGet-Paket verwenden. Ein Glob ist ein Begriff, der verwendet wird, um Muster für den Abgleich von Datei- und Verzeichnisnamen basierend auf Platzhaltern zu definieren. Das Verwenden von Platzhaltern (Globbing) ist das Definieren eines oder mehrerer Globmuster und das Abgleichen von Dateien mit inklusiven oder exklusiven Übereinstimmungen.

Muster

Um Dateien im Dateisystem basierend auf benutzerdefinierten Mustern abzugleichen, beginnen Sie mit der Instanziierung eines Matcher-Objekts. Ein Matcher kann ohne Parameter oder mit einem System.StringComparison-Parameter instanziiert werden, der intern zum Vergleichen von Mustern mit Dateinamen verwendet wird. Der Matcher macht die folgenden additiven Methoden verfügbar:

DieAddExclude- und AddInclude-Methoden können beliebig oft aufgerufen werden, um verschiedene Dateinamenmuster hinzuzufügen, die aus den Ergebnissen ausgeschlossen oder in sie eingeschlossen werden. Nachdem Sie einen Matcher instanziiert und Muster hinzugefügt haben, wird er verwendet, um Übereinstimmungen aus einem Startverzeichnis mit der Matcher.Execute-Methode auszuwerten.

Erweiterungsmethoden

Das Matcher-Objekt verfügt über mehrere Erweiterungsmethoden.

Mehrere Ausschlüsse

Um mehrere Ausschlussmuster hinzuzufügen, können Sie Folgendes verwenden:

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

Alternativ können Sie MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) verwenden, um mehrere Ausschlussmuster in einem einzelnen Aufruf hinzuzufügen:

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

Diese Erweiterungsmethode durchläuft alle bereitgestellten Muster und ruft AddExclude in Ihrem Namen auf.

Mehrere Einschlüsse

Um mehrere Einschlussmuster hinzuzufügen, können Sie Folgendes verwenden:

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

Alternativ können Sie MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) verwenden, um mehrere Einschlussmuster in einem einzelnen Aufruf hinzuzufügen:

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

Diese Erweiterungsmethode durchläuft alle bereitgestellten Muster und ruft AddInclude in Ihrem Namen auf.

Abrufen aller übereinstimmenden Dateien

Um alle übereinstimmenden Dateien abzurufen, müssen Sie Matcher.Execute(DirectoryInfoBase) direkt oder indirekt aufrufen. Für den direkten Aufruf benötigen Sie ein Suchverzeichnis:

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.

Für den C#-Code oben gilt:

Hinweis

Der DirectoryInfoWrapper-Typ wird im Microsoft.Extensions.FileSystemGlobbing.Abstractions-Namespace und der DirectoryInfo-Typ im System.IO-Namespace definiert. Um unnötige using-Anweisungen zu vermeiden, können Sie die bereitgestellten Erweiterungsmethoden verwenden.

Es gibt eine weitere Erweiterungsmethode, die ein IEnumerable<string>-Element ergibt, das die übereinstimmenden Dateien darstellt:

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.

Für den C#-Code oben gilt:

  • Instanziiert ein Matcher-Objekt.
  • Ruft AddIncludePatterns(Matcher, IEnumerable<String>[]) auf, um mehrere Dateinamenmuster hinzuzufügen, die eingeschlossen werden sollen.
  • Deklariert den Suchverzeichniswert und weist diesen zu.
  • Ruft GetResultsInFullPath mit dem searchDirectory-Wert auf, um alle übereinstimmenden Dateien als IEnumerable<string> zu erhalten.

Abgleichen von Überladungen

Das PatternMatchingResult-Objekt stellt eine Sammlung von FilePatternMatch-Instanzen dar und macht einen boolean-Wert verfügbar, der angibt, ob das Ergebnis Übereinstimmungen enthält (PatternMatchingResult.HasMatches).

Mit einer Matcher-Instanz können Sie jede der verschiedenen Match-Überladungen aufrufen, um ein Musterabgleichsergebnis zu erhalten. Die Match-Methoden legt es in die Verantwortung des Aufrufers, eine Datei oder eine Sammlung von Dateien bereitzustellen, in denen Übereinstimmungen ausgewertet werden sollen. Anders ausgedrückt: Der Aufrufer ist für die Übergabe der abzugleichenden Datei verantwortlich.

Wichtig

Wenn Sie eine der Match-Überladungen verwenden, ist keine Dateisystem-E/A beteiligt. Das gesamte Verwenden von Dateiplatzhaltern (Globbing) erfolgt im Arbeitsspeicher mit den Ein- und Ausschlussmustern der matcher-Instanz. Die Parameter der Match-Überladungen müssen keine vollqualifizierten Pfade sein. Das aktuelle Verzeichnis (Directory.GetCurrentDirectory()) wird verwendet, wenn keine Angabe erfolgt.

So gleichen Sie eine einzelne Datei ab:

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

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

Für den C#-Code oben gilt:

  • Er gleicht jede Datei mit der Dateierweiterung .md in beliebiger Verzeichnistiefe ab.
  • Wenn eine Datei mit dem Namen file.md in einem Unterverzeichnis des aktuellen Verzeichnisses vorhanden ist:
    • result.HasMatches wäre true.
    • und result.Files hätte eine Übereinstimmung.

Die zusätzlichen Match-Überladungen funktionieren auf ähnliche Weise.

Musterformate

Die in den AddExclude- und AddInclude-Methoden angegebenen Muster können die folgenden Formate verwenden, um mehrere Dateien oder Verzeichnisse abzugleichen.

  • Genauer Verzeichnis- oder Dateiname

    • some-file.txt
    • path/to/file.txt
  • Platzhalter * in Datei- und Verzeichnisnamen, die null bis viele Zeichen ohne Trennzeichen darstellen.

    Wert BESCHREIBUNG
    *.txt Alle Dateien mit Dateierweiterung .txt.
    *.* Alle Dateien mit einer Erweiterung.
    * Alle Dateien im Verzeichnis der obersten Ebene.
    .* Dateinamen, die mit „.“ beginnen.
    *word* Alle Dateien mit „word“ im Dateinamen.
    readme.* Alle Dateien mit dem Namen „readme“ mit beliebiger Dateierweiterung.
    styles/*.css Alle Dateien mit der Erweiterung „.css“ im Verzeichnis „styles/“.
    scripts/*/* Alle Dateien in „scripts/“ oder einer Unterverzeichnisebene unter „scripts/“.
    images*/* Alle Dateien in einem Ordner, die den Namen „images“ tragen oder damit beginnen.
  • Beliebige Verzeichnistiefe (/**/).

    value Beschreibung
    **/* Alle Dateien in einem beliebigen Unterverzeichnis.
    dir/ Alle Dateien in einem beliebigen Unterverzeichnis unter „dir/“.
    dir/**/* Alle Dateien in einem beliebigen Unterverzeichnis unter „dir/“.
  • Relative Pfade.

    Verwenden Sie ../shared/*, um alle Dateien in einem Verzeichnis namens „shared“ auf gleichgeordneter Ebene mit dem Basisverzeichnis abzugleichen, das an Matcher.Execute(DirectoryInfoBase) übergeben wird.

Beispiele

Betrachten Sie das folgende Beispielverzeichnis und jede Datei in ihrem entsprechenden Ordner.

📁 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

Tipp

Einige Dateierweiterungen bestehen aus Großbuchstaben, andere aus Kleinbuchstaben. Standardmäßig wird StringComparer.OrdinalIgnoreCase verwendet. Verwenden Sie den Matcher.Matcher(StringComparison)-Konstruktor, um ein anderes Zeichenfolgenvergleichsverhalten anzugeben.

So erhalten Sie alle Markdowndateien, bei denen die Dateierweiterung .md oder .mtext lautet, unabhängig von Groß-/Kleinschreibung:

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

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

Wenn Sie die Anwendung ausführen, werden Ergebnisse ähnlich wie die folgenden ausgegeben:

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

So erhalten Sie Dateien in einem Verzeichnis assets in beliebiger Tiefe:

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

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

Wenn Sie die Anwendung ausführen, werden Ergebnisse ähnlich wie die folgenden ausgegeben:

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

So rufen Sie Dateien ab, in denen der Verzeichnisname das Wort child in beliebiger Tiefe enthält und die Dateierweiterungen nicht .md, .text oder .mtext lauten:

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

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

Wenn Sie die Anwendung ausführen, werden Ergebnisse ähnlich wie die folgenden ausgegeben:

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

Siehe auch