1、前言

很多时候我们需要获取结构和层级未知的文件夹下所有的文件或是指定类型的所有文件,此时就需要使用递归操作,下面给出实现代码。我在这里新建了一个测试文件夹,其结构如下所示:

测试文件夹/
  ├─文件夹1
  │   └─1_1.docx
  │   └─1_2.docx 
  └─文件夹2
  │   └─2_1.pptx
  │   └─2_2.pptx 
  │   └─文件夹3
  │      └─3_1.xlsx
  │      └─3_2.xlsx
  │      └─文件夹4
  │         └─4_1.bmp
  │         └─4_2.bmp

在这里插入图片描述

2、调用系统方法实现递归

微软提供如下四个方法实现递归查询,只需要将SearchOption参数设置为AllDirectories即可:

  • Directory.GetFile()
  • Directory.EnumerateFiles()
  • Directory.GetFileSystemEntries()
  • Directory.EnumerateFileSystemEntries()

代码如下:

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            foreach (var file in GetFiles_1(@"D:\测试文件夹", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" }))
            {
                Console.WriteLine(file);
            }
            Console.WriteLine("-----------------------------------");
            foreach (var file in GetFiles_2(@"D:\测试文件夹", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" }))
            {
                Console.WriteLine(file);
            }
            Console.WriteLine("-----------------------------------");
            foreach (var file in GetFiles_3(@"D:\测试文件夹", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" }))
            {
                Console.WriteLine(file);
            }
            Console.WriteLine("-----------------------------------");
            foreach (var file in GetFiles_4(@"D:\测试文件夹", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" }))
            {
                Console.WriteLine(file);
            }
            Console.ReadKey();
        }

        // 使用Directory.GetFiles
        static List<string> GetFiles_1(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            foreach (var item in patterns)
            {
                files.AddRange(Directory.GetFiles(path, item, SearchOption.AllDirectories));
            }
            return files;
        }

        // 使用Directory.EnumerateFiles
        static List<string> GetFiles_2(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            foreach (var item in patterns)
            {
                files.AddRange(Directory.EnumerateFiles(path, item, SearchOption.AllDirectories));
            }
            return files;
        }

        // 使用Directory.GetFileSystemEntries
        static List<string> GetFiles_3(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            foreach (var item in patterns)
            {
                files.AddRange(Directory.GetFileSystemEntries(path, item, SearchOption.AllDirectories));
            }
            return files;
        }

        // 使用Directory.EnumerateFileSystemEntries
        static List<string> GetFiles_4(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            foreach (var item in patterns)
            {
                files.AddRange(Directory.EnumerateFileSystemEntries(path, item, SearchOption.AllDirectories));
            }
            return files;
        }
    }
}

运行结果如下图所示:

D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp
-----------------------------------
D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp
-----------------------------------
D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp
-----------------------------------
D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp

3、自定义方法实现递归

除了调用系统方法,也可以自己写一个递归方法,代码如下:

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            List<string> files = GetFiles(@"D:\测试文件夹", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" });
            foreach (var file in files)
            {
                Console.WriteLine(file);
            }
            Console.ReadKey();
        }

        static List<string> GetFiles(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            foreach (var pattern in patterns)
            {
                foreach (var file in Directory.GetFiles(path, pattern))
                {
                    files.Add(file);
                }
            }
            foreach (var directory in Directory.GetDirectories(path))
            {
                files.AddRange(GetFiles(directory, patterns));
            }
            return files;
        }
    }
}

运行结果如下图所示:

D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp

4、特殊情况的处理

上面给出的方法在大多数情况下是没问题的,但在某些特定情况下会报错。现在将文件夹路径修改一下,改为D:\,发现代码报错,如下图所示:

在这里插入图片描述

这里我们不妨先看看D盘根目录下到底有哪些文件夹,代码如下:

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            foreach (var item in Directory.GetDirectories(@"D:\"))
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

运行结果如下图所示:

在这里插入图片描述
这下明白了,D:\$RECYCLE.BIND:\System Volume Information都是隐藏的系统文件夹,代码没有权限去访问它们。此时我们就需要把上面的代码改一改,加上try...catch跳过那些无权限访问的目录,代码如下:

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            List<string> files = GetFiles(@"D:\", new string[] { "*.docx", "*.xlsx", "*.pptx", "*.bmp" });
            foreach (var file in files)
            {
                Console.WriteLine(file);
            }
            Console.ReadKey();
        }

        static List<string> GetFiles(string path, string[] patterns)
        {
            List<string> files = new List<string>();
            try
            {
                foreach (var pattern in patterns)
                {
                    foreach (var file in Directory.GetFiles(path, pattern))
                    {
                        files.Add(file);
                    }
                }
                foreach (var directory in Directory.GetDirectories(path))
                {
                    files.AddRange(GetFiles(directory, patterns));
                }
            }
            catch
            {

            }
            return files;
        }
    }
}

运行结果如下图所示:

D:\测试文件夹\文件夹1\1_1.docx
D:\测试文件夹\文件夹1\1_2.docx
D:\测试文件夹\文件夹2\2_1.pptx
D:\测试文件夹\文件夹2\2_2.pptx
D:\测试文件夹\文件夹2\文件夹3\3_1.xlsx
D:\测试文件夹\文件夹2\文件夹3\3_2.xlsx
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_1.bmp
D:\测试文件夹\文件夹2\文件夹3\文件夹4\4_2.bmp
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐