Aracılığıyla paylaş


.NET'te dosya genelleme

Bu makalede, NuGet paketiyle dosya genelleme özelliğini Microsoft.Extensions.FileSystemGlobbing kullanmayı öğreneceksiniz. Glob, joker karakterlere göre eşleşen dosya ve dizin adlarının desenlerini tanımlamak için kullanılan bir terimdir. Globbing, bir veya daha fazla glob deseni tanımlama ve kapsayıcı veya özel eşleşmelerden dosya verme işlemidir.

Desenler

Dosya sistemindeki dosyaları kullanıcı tanımlı desenlere göre eşleştirmek için, bir Matcher nesne örneği oluşturarak başlayın. , Matcher parametre olmadan veya desenleri dosya adlarıyla karşılaştırmak için dahili olarak kullanılan bir System.StringComparison parametreyle örneklenebilir. aşağıdaki Matcher ek yöntemleri kullanıma sunar:

Hem hem de AddExcludeAddInclude yöntemleri, sonuçlardan dışlanacak veya sonuçlara dahil edilecek çeşitli dosya adı desenleri eklemek için herhangi bir sayıda çağrılabilir. Bir örneği Matcher oluşturup desenleri ekledikten sonra, bu örnek yöntemiyle Matcher.Execute bir başlangıç dizininden eşleşmeleri değerlendirmek için kullanılır.

Genişletme yöntemleri

Nesnenin Matcher çeşitli uzantı yöntemleri vardır.

Birden çok dışlama

Birden çok dışlama deseni eklemek için şunları kullanabilirsiniz:

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

Alternatif olarak, tek bir çağrıda birden çok dışlama deseni eklemek için öğesini kullanabilirsiniz MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) :

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

Bu uzantı yöntemi, sizin adınıza çağrı AddExclude yapan tüm sağlanan desenler üzerinde yinelenir.

Birden çok ekleme

Birden çok ekleme deseni eklemek için şunları kullanabilirsiniz:

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

Alternatif olarak, tek bir çağrıya birden çok ekleme deseni eklemek için öğesini kullanabilirsiniz MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) :

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

Bu uzantı yöntemi, sizin adınıza çağrı AddInclude yapan tüm sağlanan desenler üzerinde yinelenir.

Eşleşen tüm dosyaları alma

Eşleşen tüm dosyaları almak için doğrudan veya dolaylı olarak aramanız Matcher.Execute(DirectoryInfoBase) gerekir. Doğrudan çağırmak için bir arama dizinine ihtiyacınız vardır:

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.

Yukarıdaki C# kodu:

Not

Türü DirectoryInfoWrapper ad alanında Microsoft.Extensions.FileSystemGlobbing.Abstractions tanımlanır ve DirectoryInfo türü ad alanında System.IO tanımlanır. Gereksiz using yönergeleri önlemek için sağlanan uzantı yöntemlerini kullanabilirsiniz.

Eşleşen dosyaları temsil eden bir IEnumerable<string> başka uzantı yöntemi vardır:

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.

Yukarıdaki C# kodu:

  • Bir nesnenin örneğini Matcher oluşturur.
  • Eklenecek birkaç dosya adı deseni eklemek için çağrılar AddIncludePatterns(Matcher, IEnumerable<String>[]) .
  • Arama dizini değerini bildirir ve atar.
  • GetResultsInFullPath Tüm eşleşen dosyaları olarak searchDirectoryvermek için verilen değeri çağırırIEnumerable<string>.

Aşırı yüklemeleri eşleştirme

PatternMatchingResult nesnesi bir örnek koleksiyonunu temsil eder ve sonucun FilePatternMatch eşleşmeleriboolean olup olmadığını gösteren bir PatternMatchingResult.HasMatches değer sunar.

Bir Matcher örnekle, desen eşleştirme sonucu almak için çeşitli Match aşırı yüklemelerden herhangi birini çağırabilirsiniz. Yöntemler, Match eşleşmelerin değerlendirildiği bir dosya veya dosya koleksiyonu sağlamak için çağıranın sorumluluğunu tersine çevirir. Başka bir deyişle, çağıran eşleşmek üzere dosyayı geçirmekten sorumludur.

Önemli

Aşırı yüklemelerden herhangi birini Match kullanırken, dosya sistemi G/Ç'sini içermez. Tüm dosya globbing örneği dahil ve dışlama desenleri matcher ile bellekte yapılır. Aşırı yükleme parametrelerinin Match tam yol olması gerekmez. Geçerli dizin (Directory.GetCurrentDirectory()) belirtilmediğinde kullanılır.

Tek bir dosyayla eşleştirmek için:

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

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

Yukarıdaki C# kodu:

  • Herhangi bir dosyayı rastgele dizin derinliğinde .md dosya uzantısıyla eşleştirir.
  • geçerli dizinden bir alt dizinde file.md adlı bir dosya varsa:
    • result.HasMatches olacaktır true.
    • ve result.Files tek bir eşleşmeye sahip olur.

Ek Match aşırı yüklemeler benzer şekillerde çalışır.

Ekleme/hariç tutmanın sıralı değerlendirmesi

Varsayılan olarak, eşleştirici önce tüm dahil etme desenlerini değerlendirir, sonra bunları eklediğiniz sıraylan bağımsız olarak tüm dışlama desenlerini uygular. Bu, daha önce dışlanmış dosyaları yeniden ekleyememenizi sağlar.

Microsoft.Extensions.FileSystemGlobbing paketinin📦 10. sürümünden itibaren, dahil etme ve dışlamaların tam olarak eklendikleri sırada işlendiği sıralı değerlendirmeyi kabul edebilirsiniz:

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);
}

Bu modda desenler birbiri ardına uygulanır:

  • **/* tüm dosyaları ekler.
  • logs/**/*, logs/ içindeki her şeyi filtreler.
  • logs/important/**/* altında logs/important/yalnızca dosyaları geri ekler.

Varsayılan oluşturucuyu kullanan mevcut kod özgün "tümü dahil, sonra tüm dışlar" davranışıyla çalışmaya devam eder.

Desen biçimleri

ve AddExclude yöntemlerinde AddInclude belirtilen desenler, birden çok dosya veya dizinle eşleştirmek için aşağıdaki biçimleri kullanabilir.

  • Tam dizin veya dosya adı

    • some-file.txt
    • path/to/file.txt
  • Dosya ve dizin adlarında, ayırıcı karakterler dahil olmayan çok sayıda karakteri temsil eden joker * karakterler.

    Değer Açıklama
    *.txt .txt dosya uzantısına sahip tüm dosyalar.
    *.* Uzantılı tüm dosyalar.
    * Üst düzey dizindeki tüm dosyalar.
    .* '.' ile başlayan dosya adları.
    *word* Dosya adında 'word' bulunan tüm dosyalar.
    readme.* Herhangi bir dosya uzantısına sahip 'benioku' adlı tüm dosyalar.
    styles/*.css 'styles/' dizinindeki '.css' uzantısına sahip tüm dosyalar.
    scripts/*/* 'script/' içindeki tüm dosyalar veya 'scripts/' altındaki bir alt dizin düzeyi.
    images*/* Bir klasördeki adı veya 'images' ile başlayan tüm dosyalar.
  • Rastgele dizin derinliği (/**/).

    Değer Açıklama
    **/* Herhangi bir alt dizindeki tüm dosyalar.
    dir/ 'dir/' altındaki herhangi bir alt dizindeki tüm dosyalar.
    dir/**/* 'dir/' altındaki herhangi bir alt dizindeki tüm dosyalar.
  • Göreli yollar.

    "shared" adlı bir dizindeki tüm dosyaları eşdüzey düzeyde verilen temel dizinle eşleştirmek için Matcher.Execute(DirectoryInfoBase)kullanın ../shared/*.

Örnekler

Aşağıdaki örnek dizini ve ilgili klasördeki her dosyayı göz önünde bulundurun.

📁 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

İpucu

Bazı dosya uzantıları büyük harfle, bazıları ise küçük harfle. Varsayılan olarak StringComparer.OrdinalIgnoreCase kullanılır. Farklı dize karşılaştırma davranışı belirtmek için oluşturucuyu Matcher.Matcher(StringComparison) kullanın.

Karakter durumundan bağımsız olarak dosya uzantısının .md veya .mtext olduğu tüm markdown dosyalarını almak için:

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

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

Uygulama çalıştırılırsa aşağıdakine benzer sonuçlar elde edilir:

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

Bir varlık dizinindeki dosyaları rastgele derinlikte almak için:

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

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

Uygulama çalıştırılırsa aşağıdakine benzer sonuçlar elde edilir:

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

Dizin adının rastgele derinlikte alt sözcüğünü içerdiği ve dosya uzantılarının .md, .text veya .mtext olmadığı dosyaları almak için:

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

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

Uygulama çalıştırılırsa aşağıdakine benzer sonuçlar elde edilir:

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

Ayrıca bkz.