Я не знаю, разрешено ли в StackOverflow публиковать собственный ответ на вопрос, но я видел, что никто еще не спрашивал об этом. Я пошел искать C# Glob и не нашел его, поэтому я написал тот, который может оказаться полезным для других.
Как реализовать глобус на С#
comment
После некоторого поиска в Google я нашел, что должен делать glob. en.wikipedia.org/wiki/Glob_(программирование)
- person tuinstoel   schedule 29.12.2008
comment
Вы бы получили больше баллов, если бы не сделали это вики сообщества. :-)
- person George Stocker   schedule 30.12.2008
comment
Почему я получил больше баллов? Я здесь новенький ...
- person Mark Maxham   schedule 02.01.2009
comment
Просто для справки: глобусы выглядят как path***.txt
- person Daniel Little   schedule 19.12.2014
comment
@Mark, потому что ответы Community Wiki не присуждают баллы, каждый голос обычно дает вам 10 баллов.
- person Daniel Little   schedule 19.12.2014
Ответы (4)
Я наткнулся на источник железа ruby, который содержит довольно аккуратный класс Glob. Его довольно легко извлечь из связанного кода.
https://github.com/IronLanguages/main/blob/master/Languages/Ruby/Ruby/Builtins/Glob.cs
person
Community
schedule
13.05.2010
Вы можете использовать командлет powershell "dir" (также известный как "Get-ChildItem") из C#.
(я не говорю, следует ли вам это делать).
Вы должны добавить эту ссылку в файл проекта (".csproj" или ".vcproj") вручную:
<Reference Include="System.Management.Automation" />
Дополнительные сведения об использовании командлетов C# см. здесь: http://www.devx.com/tips/Tip/42716
Вот рабочая программа:
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
namespace CsWildcard {
class Program {
static IEnumerable<string> CmdletDirGlobbing(string basePath, string glob){
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
// cd to basePath
if(basePath != null){
Pipeline cdPipeline = runspace.CreatePipeline();
Command cdCommand = new Command("cd");
cdCommand.Parameters.Add("Path", basePath);
cdPipeline.Commands.Add(cdCommand);
cdPipeline.Invoke(); // run the cmdlet
}
// run the "dir" cmdlet (e.g. "dir C:\*\*\*.txt" )
Pipeline dirPipeline = runspace.CreatePipeline();
Command dirCommand = new Command("dir");
dirCommand.Parameters.Add("Path", glob);
dirPipeline.Commands.Add(dirCommand);
Collection<PSObject> dirOutput = dirPipeline.Invoke();
// for each found file
foreach (PSObject psObject in dirOutput) {
PSMemberInfoCollection<PSPropertyInfo> a = psObject.Properties;
// look for the full path ("FullName")
foreach (PSPropertyInfo psPropertyInfo in psObject.Properties) {
if (psPropertyInfo.Name == "FullName") {
yield return psPropertyInfo.Value.ToString(); // yield it
}
}
}
}
static void Main(string[] args) {
foreach(string path in CmdletDirGlobbing(null,"C:\\*\\*\\*.txt")){
System.Console.WriteLine(path);
}
foreach (string path in CmdletDirGlobbing("C:\\", "*\\*\\*.exe")) {
System.Console.WriteLine(path);
}
Console.ReadKey();
}
}
}
person
Community
schedule
27.08.2013
это легко с https://github.com/dazinator/DotNet.Glob:
пример:
public static class Glob
{
public static IEnumerable<FileInfo> Exec(DirectoryInfo dir, string glob)
{
var matcher = DotNet.Globbing.Glob.Parse(glob);
return dir.EnumerateAllFiles().Where(f => matcher.IsMatch(f.FullName));
}
public static IEnumerable<FileInfo> EnumerateAllFiles(this DirectoryInfo dir)
{
foreach (var f in dir.EnumerateFiles())
{
yield return f;
}
foreach (var sub in dir.EnumerateDirectories())
{
foreach (var f in EnumerateAllFiles(sub))
{
yield return f;
}
}
}
}
person
Community
schedule
22.01.2019
Откуда вы получаете DirectoryInfo? Если у меня есть просто строковый глобус, я не хочу писать логику для извлечения базового каталога...
- person jjxtra; 14.04.2020
У вас может быть собственная версия, в которой базовый каталог — это просто текущий каталог запущенного процесса. Также пример может быть легко расширен для поддержки нескольких базовых каталогов.
- person sergeyt; 15.04.2020
"DirectoryInfo" не содержит определения ошибки "EnumerateAllFiles".
- person vee; 11.01.2021
Метод расширения @vee EnumerateAllFiles определен в классе Glob в моем фрагменте кода. Вы можете изменить его на версию без расширения. Я не уверен, почему вы получаете эту ошибку.
- person sergeyt; 17.01.2021
person
schedule
Ошибка? Мне пришлось заменить Path.Combine(head, dir) на dir, поскольку Directory.GetDirectories уже возвращает полный путь. Это вызвало ошибку с такими путями, как ..\SomeDir*.dll, поскольку ..\ дублировались Combine.
- person jturcotte; 05.03.2009
Похоже, это не работает, если вы передаете строку типа
*
функции Glob
. Делаются ли какие-то предположения относительно строки с подстановочными знаками, которую он может обрабатывать? Может быть, абсолютный путь?
- person Ben; 30.09.2011
Метод
Glob
разбивает аргумент на две части по адресу DirSep
. Код не работает, если нет Dirsep
. Добавление следующего оператора в начало метода PathHead
работает: if (! path.Contains(DirSep)) {return ".";}
.
- person AdrianHHH; 30.07.2015
@Ben Предполагается, что строка содержит
DirSep
. С изменением моего предыдущего комментария код работает для меня.
- person AdrianHHH; 17.08.2015