Как рекурсивно читать имена файлов из подпапки с помощью LINQ - PullRequest
5 голосов
/ 22 сентября 2010

Как рекурсивно читать имя файла с расширением dll из каталога и его подпапок, используя выражение LINQ или LAMBDA.

Теперь я использую цикл Nested for-each для этого. Есть ли способ сделать это, используя выражение LINQ или LAMBDA?

Ответы [ 5 ]

17 голосов
/ 22 сентября 2010

Вам не нужно использовать LINQ для этого - он встроен в каркас :

string[] files = Directory.GetFiles(directory, "*.dll",
                                    SearchOption.AllDirectories);

или , если вы используете .NET 4 :

IEnumerable<string> files = Directory.EnumerateFiles(directory, "*.dll",
                                                    SearchOption.AllDirectories);

Если честно, LINQ не очень хорош в плане рекурсии. Возможно, вы захотите написать свой собственный метод рекурсивного расширения общего назначения. Учитывая, как часто задают такой вопрос, я действительно должен сам это сделать некоторое время ...

4 голосов
/ 22 сентября 2010

это возвращает просто имена файлов + расширения:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\");
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories)
        select i.Name;

возвращает только имен файлов без расширений:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\");
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories)
        select System.IO.Path.GetFileNameWithoutExtension(i.Name);
3 голосов
/ 22 сентября 2010

Если вы действительно хотите сделать это с рекурсивным лямбда-выражением, то вы идете:

Action<string, List<string>> discoverFiles = null;

discoverFiles = new Action<string, List<string>>((dir, list) =>
    {
        try
        {
            foreach (var subDir in Directory.GetDirectories(dir))
                discoverFiles(string.Concat(subDir), list);

            foreach (var dllFile in Directory.GetFiles(dir, "*.dll"))
            {
                var fileNameOnly = Path.GetFileName(dllFile);
                if (!list.Contains(fileNameOnly))
                    list.Add(fileNameOnly);
            }
        }
        catch (IOException)
        {
            // decide what to do here
        }
    });

// usage:
var targetList = new List<string>();
discoverFiles("c:\\MyDirectory", targetList);

foreach (var item in targetList)
    Debug.WriteLine(item);

Примечание: это, вероятно, в несколько раз медленнее (и труднее читать / отлаживать / поддерживать), чем предыдущие ответы, но не останавливается, если где-то есть исключение ввода-вывода.

2 голосов
/ 22 сентября 2010
IEnumerable<string> filenames = Directory.GetFiles(searchDirectory, "*.dll",
                                                   SearchOption.AllDirectories)
                                         .Select(s => Path.GetFileName(s));

Directory.GetFiles() возвращает полный путь к файлам, которые соответствуют указанному шаблону поиска в указанном каталоге. Select проецирует каждый элемент последовательности fullpath в новую форму, только имя файла.

0 голосов
/ 22 сентября 2010

Чтение файлов и каталогов обычно выполняется с помощью классов, расположенных в пространстве имен System.IO.Поэтому первым шагом будет получение всех файлов, которые вам нужно прочитать, с использованием метода Directory.EnumerateFiles , а затем для каждого файла, который соответствует вашим критериям поиска, прочитайте содержимое, используя, например, файл .ReadAllBytes метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...