Member 12692000 Ответов: 2

Как получить файлы из специально структурированной папки по заданному пути?


У меня есть папка, внутри которой есть другие подпапки в структуре
2017-12456-12463-1023\2017\12456\12463\1023\abc.txt
2016-32456-15463-2033\2016\32456\15463\2033\xyz.txt
... so on ...
Теперь внутри каждой папки есть другие подпапки
2017-12456-12463-1023
2016-32456-15463-2033
который содержит формат txt файлы
Как я могу получить только то, что формат txt файлы из папок 1023, 2033 в вышеупомянутых структурах папок.
В VB я использовал что-то вроде

Что я уже пробовал:

Dim txtFiles = Directory.EnumerateFiles(targetDirectory, "*.txt", SearchOption.AllDirectories).Where(Function(f) f Like "*\#*\#*\#*\#*.txt").ToArray


Но как это сделать в c#?

2 Ответов

Рейтинг:
4

phil.o

Извините за позднее решение, но сегодня я был очень занят своими делами.
Вы можете попробовать:

using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

// ...

// First retrieve all files in the hierarchy
IEnumerable<string> allFiles = Directory.EnumerateFiles(targetDirectory, "*.txt", SearchOptions.AllDirectories);

// Then isolate only those which are in the directory you are interested in
Regex r = new Regex(@".+\\[\d]+\\[\d]+\\[\d]+\\[\d]+\\[^\\]+\.txt", RegexOptions.Compiled | RegexOptions.IgnoreCase);
string[] files = allFiles.Where(f => r.IsMatch(f)).ToArray();

Регулярное выражение быстро строится, но я использовал Экспрессо[^] чтобы проверить это, и это кажется правильным.

Надеюсь, это поможет. Любезно.

[Edit]: Исправлена ошибка, когда я использовал метод Match вместо правильного метода IsMatch.

[Править 2]:
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

class YourClass
{
   private static readonly Regex regex = new Regex(@".+\\[\d]+\\[\d]+\\[\d]+\\[\d]+\\[^\\]+\.txt", RegexOptions.Compiled | RegexOptions.IgnoreCase);

   // ...

   // In your method:
   string[] files = Directory.EnumerateFiles(targetDirectory, "*.txt", SearchOptions.AllDirectories).Where(f => regex.IsMatch(f)).ToArray();
}


Member 12692000

Спасибо @phil.o.
Кстати, можно ли это сделать в одной строке кода?

phil.o

Да, конечно. Если вы собираетесь использовать регулярное выражение более одного раза, я советую вам сделать его статической переменной класса, так как создание экземпляра регулярного выражения-довольно дорогостоящий процесс.
Я отредактирую свое решение через несколько минут и покажу вам, как это сделать.

Рейтинг:
0

Richard MacCutchan

VB.NET и C# использует все те же классы, так что он должен быть точно таким же. Вы можете проверить это из Каталог.Метод EnumerateFiles (System.IO)[^].


phil.o

Нет :) В C# нет эквивалента этому слову. Like VB.NET оператор, который оперирует строками, сравнимыми с SQL LIKE оператор.

Richard MacCutchan

Если вы перейдете по ссылке, которую я вам дал, то там есть пример кода C# с LINQ, чтобы делать то, что вы хотите.

phil.o

Я не оперативник :)
И проблема здесь технически не в методе EnumerateFiles, а в лямбде, передаваемой в качестве параметра функции Where: VB.NET имеет оператор LIKE, который позволяет искать шаблон с помощью подстановочных знаков; C# этого не делает.
Я думаю, что регулярное выражение здесь может сделать это.
Проблема здесь заключается в том, что OP хочет только файлы на заданной глубине, а не файлы в родительских каталогах и не файлы в поддиректориях целевого каталога. Параметр шаблона поиска метода EnumerateFiles сам по себе этого не допускает.

Richard MacCutchan

Глядя на образец в документации, оказалось, что он обеспечивает ту же функциональность. И я предположил, что оператор LIKE-это функция .NET.

Спасибо за поправку.

Member 12692000

Как я могу использовать регулярное выражение для этого? Вы можете показать какой-нибудь код? Кроме того,
родительские папки и их подпапки имеют фиксированный шаблон, как показано в вопросе.

phil.o

Пожалуйста, смотрите мое (исправленное) решение.