Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В этой статье вы узнаете, как использовать подстановку имен файлов с пакетом NuGet 📦 Microsoft.Extensions.FileSystemGlobbing.
Глоб-выражение — это термин, который используется для описания шаблонов для сопоставления имен файлов и каталогов на основе подстановочных знаков. Глоббинг — это процесс определения одного или нескольких шаблонов глобов и получения файлов из включительных или исключительных совпадений.
Шаблоны
Чтобы сопоставить файлы в файловой системе на основе определяемых пользователем шаблонов, начните с создания экземпляра объекта 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>[]) для добавления нескольких шаблонов исключения в один вызов:
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>[]) для добавления нескольких шаблонов включения в один вызов:
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>[]), чтобы добавить несколько шаблонов имен файлов для включения.
- Объявляет и присваивает значение каталога поиска.
- Создает экземпляр DirectoryInfo из заданного
searchDirectory. - Создает экземпляр DirectoryInfoWrapper из
DirectoryInfo, оболочкой которого он является. - Вызывает
Execute, которому передан экземплярDirectoryInfoWrapperдля получения объекта PatternMatchingResult.
Примечание.
Тип DirectoryInfoWrapper определен в пространстве имен Microsoft.Extensions.FileSystemGlobbing.Abstractions, а тип DirectoryInfo определен в пространстве имен System.IO. Чтобы избежать ненужных using директив, можно использовать предоставленные методы расширения.
Существует другой метод расширения, который возвращает IEnumerable<string>, представляющий соответствующие файлы:
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>[]), чтобы добавить несколько шаблонов имен файлов для включения.
- Объявляет и присваивает значение каталога поиска.
- Вызывает
GetResultsInFullPathс заданным значениемsearchDirectoryдля получения всех соответствующих файлов в видеIEnumerable<string>.
Перегрузка функций
Объект PatternMatchingResult представляет коллекцию экземпляров FilePatternMatch и предоставляет значение, указывающее, совпадает ли результат с результатомboolean.PatternMatchingResult.HasMatches
С помощью экземпляра Matcher можно вызвать любую из различных перегрузок Match, чтобы получить результат сопоставления шаблона. Методы Match перекладывают на вызывающий объект ответственность за предоставление файла или коллекции файлов, которые должны оцениваться на предмет совпадений. Иными словами, вызывающая сторона отвечает за передачу файла для сопоставления.
Внимание
При использовании любой из перегрузок Match операции ввода-вывода файловой системы не используются. Глоббинг файлов полностью выполняется в памяти с использованием шаблонов включения и исключения для экземпляра 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будет иметь одно совпадение.
-
Дополнительные перегрузки Match работают аналогичным образом.
Упорядоченная оценка включения и исключения
По умолчанию сопоставитель сначала обрабатывает все шаблоны включения, затем применяет все шаблоны исключения, независимо от порядка их добавления. Это означает, что вы не можете повторно включать файлы, которые ранее были исключены.
Начиная с версии 10 📦 пакета Microsoft.Extensions.FileSystemGlobbing, можно выбрать упорядоченную оценку, где в том числе и исключения обрабатываются точно в последовательности, в которой они были добавлены:
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);
}
В этом режиме шаблоны применяются друг за другом:
-
**/*добавляет все файлы. -
logs/**/*отфильтровывает все вlogs/. -
logs/important/**/*добавляет обратно только файлы подlogs/important/.
Существующий код, использующий конструктор по умолчанию, будет продолжать выполняться с исходным поведением "сначала все включения, затем все исключения".
Форматы шаблонов
Шаблоны, указанные в методах AddExclude и AddIncludeмогут использовать следующие форматы для сопоставления нескольких файлов или каталогов.
Точное имя каталога или файла
some-file.txtpath/to/file.txt
Подстановочные знаки
*в именах файлов и каталогов, представляющих ноль и многие символы, не включая символы-разделители.значение Описание *.txtВсе файлы с расширением .txt. *.*Все файлы с расширением. *Все файлы в каталоге верхнего уровня. .*Имена файлов, начинающиеся с ".". *word*Все файлы с "word" в имени файла. readme.*Все файлы с именем "readme" и любым расширением файла. styles/*.cssВсе файлы с расширением ".css" в каталоге "styles/". scripts/*/*Все файлы в папке "scripts/" или в одном уровне вложенной папки под "scripts/". images*/*Все файлы в папке с именем "images" или именем, начинающимся с "images". Произвольная глубина каталога (
/**/).значение Описание **/*Все файлы в любом подкаталоге. dir/Все файлы в любом подкаталоге каталога "dir/". dir/**/*Все файлы в любом подкаталоге каталога "dir/". Относительные пути.
Чтобы сопоставить все файлы в каталоге с именем "shared" на уровне, параллельном базовому каталогу, предоставленному Matcher.Execute(DirectoryInfoBase), используйте
../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).
Для получения всех Markdown файлов с расширением .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