【问题标题】:Is there a way to use the search option: All directories but it skips to the next folder after searching first layer of the folder有没有办法使用搜索选项:所有目录,但在搜索文件夹的第一层后跳到下一个文件夹
【发布时间】:2020-02-11 20:18:06
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# search directory


    【解决方案1】:

    你可以试试嵌套查询:

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

    【讨论】:

    • 不管怎样,"*" 是默认搜索模式,TopDirectoryOnly 是默认搜索选项,因此不必明确说明。
    • @Rufus L:你说的很对,我已经明确输入了SearchOption.TopDirectoryOnly 来表明这个想法; SearchOption.TopDirectoryOnly"*" 都可以跳过
    • @Dmitry Bychenko 如果我想在跳转到下一个文件夹之前搜索第一个和第二个子目录,我该怎么做?
    • @LeoX:同样是嵌套查询,但多了一层
    • @Dmitry Bychenko 谢谢!这帮助很大。
    猜你喜欢
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2011-08-07
    • 1970-01-01
    相关资源
    最近更新 更多