如何递归列出C#中目录中的所有文件?

294 .net c#

如何递归列出目录中的所有文件和C#中的子目录?

Mar*_*ell 412

请注意,在.NET 4.0中,存在(假设)基于迭代器(而不是基于数组)的文件函数:

foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
    Console.WriteLine(file);
}
Run Code Online (Sandbox Code Playgroud)

目前我会使用下面的东西; 如果您无法访问单个子目录,则内置递归方法会很容易中断...; 的Queue<string>使用避免了过多的调用堆栈递归和迭代器块避免了一个巨大的数组我们.

static void Main() {
    foreach (string file in GetFiles(SOME_PATH)) {
        Console.WriteLine(file);
    }
}

static IEnumerable<string> GetFiles(string path) {
    Queue<string> queue = new Queue<string>();
    queue.Enqueue(path);
    while (queue.Count > 0) {
        path = queue.Dequeue();
        try {
            foreach (string subDir in Directory.GetDirectories(path)) {
                queue.Enqueue(subDir);
            }
        }
        catch(Exception ex) {
            Console.Error.WriteLine(ex);
        }
        string[] files = null;
        try {
            files = Directory.GetFiles(path);
        }
        catch (Exception ex) {
            Console.Error.WriteLine(ex);
        }
        if (files != null) {
            for(int i = 0 ; i < files.Length ; i++) {
                yield return files[i];
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Wikis并使用`Console`你需要添加`using System;` - 但是因为IDE可以为你添加所有必需的`using`指令*(ctrl +.),因为我们没有使用任何异国情调在这里,通常不包括它们.哎呀,你还需要一个"类"定义等等.只要说' (7认同)
  • @MarcGravell 我们现在处于 .net 核心和 Visual Studio Code 世界中,因此在 *any* 示例 .net 代码中始终欢迎使用 Using 语句,以节省一系列搜索和毫无意义的“牦牛剃须” (4认同)
  • 对于所有想知道`*.*`还包括没有*文件扩展名的文件*的人:是的,它确实在一分钟前测试过. (3认同)
  • 要使用它,您需要添加 `using System.IO;` (3认同)
  • 在符号链接等方面,这将如何工作? (2认同)

Joh*_*n T 180

文章涵盖了所有你需要的.除了搜索文件和比较名称外,只需打印出名称即可.

它可以像这样修改:

static void DirSearch(string sDir)
{
    try
    {
        foreach (string d in Directory.GetDirectories(sDir))
        {
            foreach (string f in Directory.GetFiles(d))
            {
                Console.WriteLine(f);
            }
            DirSearch(d);
        }
    }
    catch (System.Exception excpt)
    {
        Console.WriteLine(excpt.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 此方法不会列出初始目录的文件,只会列出sub dirs和lower.我会将GetFiles移到GetDirectories之外 (77认同)
  • 你应该避免捕获异常 - 你真的想捕获一个OutOfMemoryException吗?只抓住你能处理的东西. (3认同)
  • @GONeale是正确的。对于用户来说,不要期望输入根目录的文件列表是不太合理的。输入单词是这里的关键。输入它是有原因的。 (2认同)
  • 我必须在内部foreach循环周围添加一个try catch,否则它不会继续出现访问被拒绝的错误 (2认同)

小智 88

Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
Run Code Online (Sandbox Code Playgroud)

  • @Romil我不相信这段代码片段试图表明完整的功能,只是OP正在寻求的原始功能.感谢分享,Pescuma! (5认同)
  • 您将收到此解决方案的"UnauthorizedAccessException".您应该有一个可以处理这样的错误的解决方案. (3认同)
  • 如果登录用户无权访问某些文件夹,如何避免错误. (2认同)

Vik*_*kov 17

最短记录

string files = Directory.GetFiles(@"your_path", "*.jpg", SearchOption.AllDirectories);
Run Code Online (Sandbox Code Playgroud)

  • 那不是“string[] files”吗? (3认同)
  • 我不明白为什么首先添加这个答案以及为什么它有这么多的赞成票。这与在此答案之前 6 年添加的 /sf/answers/1627772331/ 的答案完全相同。如果您想添加字符串声明和 @ 以避免需要转义斜杠,为什么不改进旧答案呢? (2认同)

Joh*_*ter 12

至少在.NET 4.5中,这个版本要短得多,并且还有额外的好处,可以评估包含在列表中的任何文件条件:

    /// </remarks>
    public static IEnumerable<string> GetAllFiles(string path, Func<FileInfo, bool> checkFile = null)
    {
        string mask = Path.GetFileName(path);
        if (string.IsNullOrEmpty(mask))
            mask = "*.*";
        path = Path.GetDirectoryName(path);
        string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories);
        foreach (string file in files)
        {
            if (checkFile == null || checkFile(new FileInfo(file)))
                yield return file;
        }
    }
Run Code Online (Sandbox Code Playgroud)

使用如下:

        string folder = Config.TestInput();
        string mask = folder + "*.*";
        var list = UT.GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();
        Assert.AreNotEqual(0, list.Count);
        var lastQuarter = DateTime.Now.AddMonths(-3);
        list = UT.GetAllFiles(mask, (info) => info.CreationTime >= lastQuarter).ToList();
        Assert.AreNotEqual(0, list.Count);
Run Code Online (Sandbox Code Playgroud)


Raz*_*dze 11

IEnumerable<string> GetFilesFromDir(string dir) =>
 Directory.EnumerateFiles(dir).Concat(
 Directory.EnumerateDirectories(dir)
          .SelectMany(subdir => GetFilesFromDir(subdir)));
Run Code Online (Sandbox Code Playgroud)


小智 5

这是我们如何获取文件作为其子目录的 FileInfo 的方法,

var dir = new DirectoryInfo(rootPath);
FileInfo[] files = dir.GetFiles("*.*", SearchOption.AllDirectories);
Run Code Online (Sandbox Code Playgroud)