.NET でのファイルのグロビング
この記事では、Microsoft.Extensions.FileSystemGlobbing
NuGet パッケージでファイルのグロビングを使用する方法について説明します。 glob は、ワイルドカードに基づいてファイル名とディレクトリ名を照合するパターンを定義するために使用される用語です。 グロビングは、1 つまたは複数の glob パターンを定義し、包含または排他的な一致からファイルを生成する行為です。
パターン
ユーザー定義のパターンに基づいてファイル システム内のファイルを照合するには、まず、Matcher オブジェクトをインスタンス化します。 Matcher
のインスタンスを、パラメーターを指定せずに作成できます。または、パターンをファイル名と比較するために内部的に使用される System.StringComparison パラメーターを指定できます。 Matcher
は、以下の追加のメソッドを公開します。
AddExclude
および AddInclude
メソッドの両方を何回でも呼び出すことができ、さまざまなファイル名パターンを追加して、結果から除外するか、含めるかを指定できます。 Matcher
のインスタンスを作成し、パターンを追加すると、Matcher.Execute メソッドで、開始ディレクトリからの一致を評価するために使用されます。
拡張メソッド
Matcher
オブジェクトには、いくつかの拡張メソッドがあります。
複数の除外
複数の除外パターンを追加するには、以下を使用できます。
Matcher matcher = new();
matcher.AddExclude("*.txt");
matcher.AddExclude("*.asciidoc");
matcher.AddExclude("*.md");
または、MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) を使用して、1 回の呼び出しで複数の除外パターンを追加することもできます。
Matcher matcher = new();
matcher.AddExcludePatterns(new [] { "*.txt", "*.asciidoc", "*.md" });
この拡張メソッドでは、ユーザーに代わって、指定したすべてのパターンが反復処理され、AddExclude が呼び出されます。
複数の包含
複数の包含パターンを追加するには、以下を使用できます。
Matcher matcher = new();
matcher.AddInclude("*.txt");
matcher.AddInclude("*.asciidoc");
matcher.AddInclude("*.md");
または、MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) を使用して、1 回の呼び出しで複数の包含パターンを追加することもできます。
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });
この拡張メソッドでは、ユーザーに代わって、指定したすべてのパターンが反復処理され、AddInclude が呼び出されます。
一致するすべてのファイルを取得する
一致するすべてのファイルを取得するには、直接または間接的に Matcher.Execute(DirectoryInfoBase) を呼び出す必要があります。 直接呼び出すには、検索ディレクトリが必要です。
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.
前述の C# コードでは、次のことが行われます。
- Matcher オブジェクトをインスタンス化します。
- AddIncludePatterns(Matcher, IEnumerable<String>[]) を呼び出して、含めるファイル名のパターンをいくつか追加します。
- 検索ディレクトリの値を宣言して割り当てます。
- 与えられた
searchDirectory
から DirectoryInfo のインスタンスを作成します。 - それがラップする
DirectoryInfo
から DirectoryInfoWrapper のインスタンスを作成します。 DirectoryInfoWrapper
インスタンスを指定してExecute
を呼び出し、PatternMatchingResult オブジェクトを生成します。
注意
DirectoryInfoWrapper
型は Microsoft.Extensions.FileSystemGlobbing.Abstractions
名前空間に定義され、DirectoryInfo
型は System.IO
名前空間に定義されます。 不要な using
ディレクティブを回避するには、提供されている拡張メソッドを使用できます。
一致するファイルを表す IEnumerable<string>
を生成する拡張メソッドがもう 1 つあります。
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.
前述の C# コードでは、次のことが行われます。
- Matcher オブジェクトをインスタンス化します。
- AddIncludePatterns(Matcher, IEnumerable<String>[]) を呼び出して、含めるファイル名のパターンをいくつか追加します。
- 検索ディレクトリの値を宣言して割り当てます。
searchDirectory
値を指定してGetResultsInFullPath
を呼び出し、一致するすべてのファイルをIEnumerable<string>
として生成します。
オーバーロードを照合する
PatternMatchingResult オブジェクトは FilePatternMatch インスタンスのコレクションを表し、結果に一致があるかどうかを示す boolean
値を公開しますPatternMatchingResult.HasMatches。
Matcher
インスタンスを使用すると、別々の Match
オーバーロードのいずれかを呼び出して、パターン マッチングの結果を取得できます。 Match
メソッドは、一致を評価するためのファイルまたはファイルのコレクションを提供する呼び出し側の責任を逆転させます。 つまり、呼び出し元が、一致するファイルを渡す責任があります。
重要
いずれかの Match
オーバーロードを使用する場合、ファイルシステム I/O は関係しません。 すべてのファイルのグロビングは、matcher
インスタンスの包含および除外パターンを使用して、メモリ内で実行されます。 Match
オーバーロードのパラメーターは、完全修飾パスである必要はありません。 指定されていない場合は、現在のディレクトリ (Directory.GetCurrentDirectory()) が使用されます。
単一のファイルを照合するには:
Matcher matcher = new();
matcher.AddInclude("**/*.md");
PatternMatchingResult result = matcher.Match("file.md");
前述の C# コードでは、次のことが行われます。
- 任意のディレクトリの深さで、ファイル拡張子が .md のファイルを照合します。
- file.md という名前のファイルが現在のディレクトリのサブディレクトリに存在する場合:
result.HasMatches
はtrue
になります。result.Files
は一致が 1 つになります。
追加の Match
オーバーロードは、同様の方法で動作します。
パターンの形式
AddExclude
および AddInclude
メソッドで指定されるパターンは、次の形式を使用して、複数のファイルまたはディレクトリを照合することができます。
ディレクトリまたはファイルの正確な名前
some-file.txt
path/to/file.txt
ファイルおよびディレクトリ名内の
*
ワイルドカード。区切り文字を含まない 0 個以上の文字を表します。値 説明 *.txt
ファイル拡張子が .txt のすべてのファイル。 *.*
拡張子を持つすべてのファイル。 *
最上位のディレクトリにあるすべてのファイル。 .*
'.'.で始まるファイル名。 *word*
ファイル名に ' word ' が含まれるすべてのファイル。 readme.*
任意のファイル拡張子を持つ ' readme ' という名前のすべてのファイル。 styles/*.css
ディレクトリ 'styles/' 内にあり、拡張子が '.css' のすべてのファイル。 scripts/*/*
'scripts/' または 'scripts/' の下の 1 つのサブディレクトリ レベルにあるすべてのファイル。 images*/*
名前が 'images' に等しいまたはそれで始まるフォルダー内のすべてのファイル。 任意のディレクトリの深さ (
/**/
)。値 説明 **/*
任意のサブディレクトリ内のすべてのファイル。 dir/
'dir/' の下の任意のサブディレクトリにあるすべてのファイル。 dir/**/*
'dir/' の下の任意のサブディレクトリにあるすべてのファイル。 相対パス。
Matcher.Execute(DirectoryInfoBase) に与えられたベース ディレクトリの兄弟レベルにある "shared " という名前のディレクトリ内のすべてのファイルを照合するには、
../shared/*
を使用します。
例
次の例のディレクトリと、それに対応するフォルダー内の各ファイルについて考えてみましょう。
📁 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
ヒント
一部のファイル拡張子は大文字で、他のファイル拡張子は小文字です。 既定では StringComparer.OrdinalIgnoreCase が使用されます。 異なる文字列比較の動作を指定するには、Matcher.Matcher(StringComparison) コンストラクターを使用します。
ファイル拡張子が .md または .mtext のいずれかであるマークダウン ファイルを、大文字小文字に関係なくすべて取得するには:
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "**/*.md", "**/*.mtext" });
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
アプリケーションを実行すると、次のような結果が出力されます。
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
assets ディレクトリ内の任意の深さのファイルを取得するには:
Matcher matcher = new();
matcher.AddInclude("**/assets/**/*");
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
アプリケーションを実行すると、次のような結果が出力されます。
C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg
ディレクトリ名に child という単語が任意の深さで含まれ、ファイル拡張子が .md、 .text、または .mtext ではないファイルを取得するには:
Matcher matcher = new();
matcher.AddInclude("**/*child/**/*");
matcher.AddExcludePatterns(
new[]
{
"**/*.md", "**/*.text", "**/*.mtext"
});
foreach (string file in matcher.GetResultsInFullPath("parent"))
{
Console.WriteLine(file);
}
アプリケーションを実行すると、次のような結果が出力されます。
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
こちらもご覧ください
.NET