Я пытаюсь использовать Directory.GetFiles()
метод для получения списка файлов нескольких типов, таких как mp3
's и jpg
'. Я попробовал оба из следующих без удачи:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
Есть ли способ сделать это за один звонок?
c#
filesystems
.net
Джейсон З
источник
источник
Ответы:
Для .NET 4.0 и новее
Для более ранних версий .NET,
редактировать: пожалуйста, прочитайте комментарии. Улучшение, которое предлагает Пол Фарри , и проблема памяти / производительности, на которую указывает Christian.K , оба очень важны.
источник
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
сDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx , что позволит избежать проблем с памятью , которые @ Christian.K упоминает.Как насчет этого:
Я нашел это здесь (в комментариях): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
источник
Parallel.ForEach
чтобы получить их параллельноЕсли у вас есть большой список расширений для проверки, вы можете использовать следующее. Я не хотел создавать много операторов OR, поэтому я изменил то, что написал lette.
источник
Path.GetExtension
возвращает «.ext», а не «* .ext» (по крайней мере, в 3.5+)..abc
, который поддерживается.abcd
. Будет соответствовать, хотя это не должно. Чтобы исправить:supportedExtensions = ".jpg|.abcd|";
с.Contains(Path.GetExtension(s).ToLower() + "|")
. То есть включите ваш символ-разделитель в тест. ВАЖНО: ваш символ-разделитель также должен быть после последней записи в SupportExceptions.за
Вы могли бы:
Directory.EnumerateFiles
для повышения производительности (В чем разница между Directory.EnumerateFiles и Directory.GetFiles? ).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
а не.ToLower().EndsWith("aspx")
)Но реальная выгода
EnumerateFiles
проявляется, когда вы разделяете фильтры и объединяете результаты:Это становится немного быстрее, если вам не нужно превращать их в шарики (то есть
exts = new[] {"*.mp3", "*.jpg"}
уже).Оценка производительности на основе следующего теста LinqPad (примечание:
Perf
просто повторяет делегата 10000 раз) https://gist.github.com/zaus/7454021(перепечатано и расширено от «дубликата», поскольку этот вопрос специально не запрашивал LINQ: множественные расширения файлов searchPattern для System.IO.Directory.GetFiles )
источник
.FilterFiles(path, "jpg", "gif")
усмотрение решение, является ли «упрощенное использование» (т.е. ) лучше, чем «явные глобусы» (т.е..FilterFiles(path, "*.jpg", "*.gif")
).Я знаю, что это старый вопрос, но LINQ: (.NET40 +)
источник
file.ToLower()
чтобы легко сопоставлять расширения в верхнем регистре. И почему бы сначала не извлечь расширение, чтобы Regex не приходилось проверять весь путь:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
Существует также решение для спуска, которое, похоже, не имеет никаких затрат памяти или производительности и выглядит довольно элегантно:
источник
Другой способ использовать Linq, но без необходимости возвращать все и фильтровать это в памяти.
На самом деле это 2 звонка
GetFiles()
, но я думаю, что это соответствует духу вопроса и возвращает их в одном перечислении.источник
Нет. Попробуйте следующее:
Взято с: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
источник
Позволять
затем
или
источник
Я не могу использовать
.Where
метод, потому что я программирую на .NET Framework 2.0 (Linq поддерживается только в .NET Framework 3.5+).Код ниже не чувствителен к регистру (так будет
.CaB
или.cab
будет указан тоже).источник
Следующая функция выполняет поиск по нескольким шаблонам, разделенным запятыми. Вы также можете указать исключение, например: «! Web.config» будет искать все файлы и исключать «web.config». Шаблоны могут быть смешаны.
Применение:
источник
источник
file.Extension.ToLower()
это плохая практика.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
в .NET 2.0 (без Linq):
Тогда используйте это:
источник
источник
Просто нашел другой способ сделать это. Все еще не одна операция, но выбрасывание, чтобы увидеть, что другие люди думают об этом.
источник
Что о
источник
Сделайте для расширений нужную вам строку, например «.mp3.jpg.wma.wmf», а затем проверьте, содержит ли каждый файл нужное вам расширение. Это работает с .net 2.0, поскольку он не использует LINQ.
Преимущество этого подхода в том, что вы можете добавлять или удалять расширения без редактирования кода, то есть для добавления изображений в формате png, просто напишите myExtensions = ". Jpg.mp3.png".
источник
s
источник
Нет ... Я считаю, что вам нужно сделать столько звонков, сколько вам нужно.
Я сам создал бы функцию, получающую массив из строк с нужными мне расширениями, а затем выполнял бы итерацию по этому массиву, делая все необходимые вызовы. Эта функция будет возвращать общий список файлов, соответствующих отправленным мною расширениям.
Надеюсь, поможет.
источник
У меня была та же проблема, и я не мог найти правильное решение, поэтому я написал функцию под названием GetFiles:
Эта функция будет вызываться
Directory.Getfiles()
только один раз.Например, вызовите функцию следующим образом:
РЕДАКТИРОВАТЬ: Чтобы получить один файл с несколькими расширениями, используйте этот:
Например, вызовите функцию следующим образом:
источник
Интересно, почему опубликовано так много «решений»?
Если мое понимание новичка о том, как работает GetFiles, верно, есть только два варианта, и любое из приведенных выше решений может быть сведено к следующему:
GetFiles, затем фильтр: быстро, но убийца памяти из-за хранения служебных данных до применения фильтров
Фильтровать при GetFiles: чем медленнее, тем больше фильтров установлено, но низкое потребление памяти, так как никакие накладные расходы не сохраняются.
Это объясняется в одном из приведенных выше постов с впечатляющим тестом: каждый параметр фильтра вызывает отдельную операцию GetFile, поэтому одна и та же часть жесткого диска читается несколько раз.
На мой взгляд, вариант 1) лучше, но использование SearchOption.AllDirectories для таких папок, как C: \, потребовало бы огромных объемов памяти.
Поэтому я бы просто сделал рекурсивный под-метод, который просматривает все подпапки, используя опцию 1)
Это должно вызывать только 1 операцию GetFiles для каждой папки и, следовательно, быть быстрым (вариант 1), но использовать только небольшой объем памяти, так как фильтры применяются после чтения каждой подпапки -> служебная информация удаляется после каждой подпапки.
Пожалуйста, поправьте меня, если я ошибаюсь. Я, как я уже сказал, довольно новичок в программировании, но хочу получить более глубокое понимание вещей, чтобы в конечном итоге стать хорошим в этом :)
источник
Если вы используете VB.NET (или импортировали зависимость в ваш проект C #), на самом деле существует удобный метод, который позволяет фильтровать по нескольким расширениям:
В VB.NET это может быть доступно через пространство имен My:
К сожалению, эти удобные методы не поддерживают лениво оцененный вариант, как это
Directory.EnumerateFiles()
делает.источник
я не знаю, какое решение лучше, но я использую это:
источник
Вот простой и элегантный способ получения отфильтрованных файлов
источник
Или вы можете просто преобразовать строку расширений в строку ^
источник
Использование шаблона поиска GetFiles для фильтрации расширения небезопасно !! Например, у вас есть два файла Test1.xls и Test2.xlsx, и вы хотите отфильтровать файл xls, используя шаблон поиска * .xls, но GetFiles возвращает оба Test1.xls и Test2.xlsx. Я не знал об этом и получил ошибку в работе среда, когда некоторые временные файлы внезапно обрабатывались как правильные файлы. Шаблон поиска был * .txt, а временные файлы были названы * .txt20181028_100753898. Таким образом, шаблон поиска нельзя доверять, необходимо также добавить дополнительную проверку имен файлов.
источник