.net中的递归文件搜索

时间:2009-01-13 01:52:23

标签: file io .net file-search

我需要在驱动器(C:,D:etc)中搜索特定文件类型(扩展名为.xml,.csv,.xls)。如何预先形成递归搜索以循环所有目录和内部目录并返回文件所在的完整路径?或者我在哪里可以获得相关信息?

VB.NET或C#

由于

编辑〜我遇到了一些错误,比如无法访问系统卷访问被拒绝等。有谁知道我在哪里可以看到实现文件搜索的一些代码?我只需要搜索选定的驱动器并返回找到的所有文件的文件类型的完整路径。

3 个答案:

答案 0 :(得分:53)

System.IO.Directory.GetFiles(@"c:\", "*.xml", SearchOption.AllDirectories);

答案 1 :(得分:21)

这个怎么样?它避免了内置递归搜索经常抛出的异常(即你对单个文件夹的访问被拒绝,你的整个搜索都会死掉),并且被懒惰地评估(即它在找到结果后立即返回结果,而不是缓冲2000结果)。惰性行为允许您构建响应式UI等,并且也适用于LINQ(尤其是First()Take()等)。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
static class Program { // formatted for vertical space
    static void Main() {
        foreach (string match in Search("c:\\", "*.xml")) {
            Console.WriteLine(match);
        }
    }
    static IEnumerable<string> Search(string root, string searchPattern) {
        Queue<string> dirs = new Queue<string>();
        dirs.Enqueue(root);
        while (dirs.Count > 0) {
            string dir = dirs.Dequeue();

            // files
            string[] paths = null;
            try {
                paths = Directory.GetFiles(dir, searchPattern);
            } catch { } // swallow

            if (paths != null && paths.Length > 0) {
                foreach (string file in paths) {
                    yield return file;
                }
            }

            // sub-directories
            paths = null;
            try {
                paths = Directory.GetDirectories(dir);
            } catch { } // swallow

            if (paths != null && paths.Length > 0) {
                foreach (string subDir in paths) {
                    dirs.Enqueue(subDir);
                }
            }
        }
    }
}

答案 2 :(得分:5)

看起来recls库 - 代表 rec ursive ls - 现在有pure .NET implementation。我只是read about it in Dr Dobb's

将用作:

using Recls;
using System;
static class Program { // formatted for vertical space
    static void Main() {
        foreach(IEntry e in FileSearcher.Search(@"c:\", "*.xml|*.csv|*.xls")) {
            Console.WriteLine(e.Path);
        }
    }