Есть ли способ использовать параметр поиска: все каталоги, но он переходит к следующей папке после поиска первого слоя папки - PullRequest
1 голос
/ 15 октября 2019

У меня очень большая папка с несколькими подкаталогами , файлы, которые я хочу найти, расположены только в первом слое этих подкаталогов, я попробовал SearchOption.AllDirectories но это занимает слишком много времени. Есть ли способ для функции не искать в подкаталоге весь , а только в первом слое этого?

Я пытался использовать Directory.EnumerateFiles, но он все ещезанимает слишком много времени .

foreach (string file in Directory.EnumerateFiles(
   @"\\Computer1\", 
    "Application.exe", 
     SearchOption.AllDirectories)) {
  ...
}

1 Ответ

4 голосов
/ 15 октября 2019

Вы можете попробовать вложенный запрос:

  1. Перечислить главные каталоги в пределах @"\\Computer1\"
  2. Перечислить файлы в этих верхних каталогах:

Код:

using System.IO;
using System.Linq;

...

var files = Directory
  .EnumerateDirectories( @"\\Computer1\", "*", SearchOption.TopDirectoryOnly)
  .SelectMany(dir => Directory
     .EnumerateFiles(dir, "Application.exe", SearchOption.TopDirectoryOnly)); 

foreach (var file in files) {
...
}

Редактировать: Если вы хотите перечислить файлы 1-го и 2-гоУровни, вы можете вложить запрос еще раз :

var files = Directory
  .EnumerateDirectories( @"\\Computer1\", "*", SearchOption.TopDirectoryOnly)
  .SelectMany(dir => Directory
      // 1st level
     .EnumerateFiles(dir, "Application.exe", SearchOption.TopDirectoryOnly)
      // 2nd level
     .Concat(Directory
       .EnumerateDirectories(dir, "*", SearchOption.TopDirectoryOnly)
       .SelectMany(subdir => Directory.EnumerateFiles(subdir, "Application.exe", SearchOption.TopDirectoryOnly)))); 

В общий случай мы можем реализовать

private static IEnumerable<string> EnumerateDirectories(string root, int level) {
  int current = 0;

  Queue<string> agenda = new Queue<string>();

  agenda.Enqueue(root);

  while (current <= level) {
    var list = agenda.ToList();

    agenda.Clear();

    foreach (var dir in list) {
      if (current > 0)
        yield return dir;

      if (current < level)
        foreach (var subdir in Directory.EnumerateDirectories(dir))
          agenda.Enqueue(subdir);
    }

    current += 1;
  }
}

Использовать его:

// All subdirectories, up and including 2nd level
var files = EnumerateDirectories(@"\\Computer1\", 2)
  .SelectMany(dir => Directory
     .EnumerateFiles(dir, "Application.exe", SearchOption.TopDirectoryOnly));

foreach (var file in files) {
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...