首页 > 解决方案 > 有没有办法使用搜索选项:所有目录,但在搜索文件夹的第一层后跳到下一个文件夹

问题描述

我有一个非常大的文件夹,里面有多个子目录,我要查找的文件只位于这些子目录的第一层,我试过了,SearchOption.AllDirectories但它需要太多时间。有没有办法让函数不搜索整个子目录而只搜索它的第一层

我尝试过使用Directory.EnumerateFiles,但它仍然占用太多时间

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

标签: c#searchdirectory

解决方案


您可以尝试嵌套查询:

  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) {
...
}

编辑:如果要枚举第一级和第二级的文件,可以再次嵌套查询:

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) {
  ...
}

推荐阅读