最推荐使用 Directory.EnumerateFiles 处理大目录或需逐个处理的场景,它返回 IEnumerable,内存占用低、默认跳过无权限子目录;Directory.GetFiles 适合小目录且需一次性获取全部路径,但易内存暴涨且不支持动态筛选。

Directory.GetFiles 一次性获取所有文件路径
最直接的方式是用 Directory.GetFiles,它返回 string[],包含匹配条件的完整文件路径。默认不递归,只查当前目录:
string[] files = Directory.GetFiles(@"C:\MyFolder");
加第三个参数可递归搜索:SearchOption.AllDirectories;用第二个参数可过滤扩展名,比如 "*.txt"。
- 注意:如果目录不存在或无权限,会直接抛
DirectoryNotFoundException或UnauthorizedAccessException,不能靠返回空数组判断失败 - 大目录下容易内存暴涨——所有路径一次性加载进内存,不用
foreach遍历时也已分配完毕 - 不支持按修改时间、大小等动态条件筛选,纯字符串匹配
Directory.EnumerateFiles 更适合逐个处理大目录
当文件数多、或只需遍历处理(如日志扫描、批量重命名),优先选 Directory.EnumerateFiles。它返回 IEnumerable,边枚举边 yield,内存占用低:
foreach (string file in Directory.EnumerateFiles(@"C:\Logs", "*.log", SearchOption.AllDirectories))
{
Console.WriteLine(file);
// 处理单个文件,不会提前加载全部路径
}
- 遇到权限不足的子目录时,默认跳过(不抛异常),但可通过
try/catch捕获UnauthorizedAccessException并继续 - 不支持通配符组合(如
"a*.log|b*.txt"),一次只能传一个模式 - 返回路径格式依赖输入路径写法:若输入相对路径,结果也是相对路径;建议统一用绝对路径避免歧义
用 DirectoryInfo + GetFiles 需要手动处理递归和异常
DirectoryInfo 提供面向对象接口,GetFiles() 方法行为类似 Directory.GetFiles,但允许复用实例、检查属性(如 Parent、Exists):
var dir = new DirectoryInfo(@"C:\Data");
if (!dir.Exists) return;
FileInfo[] files = dir.GetFiles("*.config");
- 递归需手动实现:调用
GetDirectories()后逐层GetFiles(),比SearchOption.AllDirectories冗长且易漏异常处理 - 每个
FileInfo实例带文件元数据(LastWriteTime、Length等),适合需要属性再过滤的场景,但创建开销比纯路径字符串大 - 对符号链接(symlink)或挂载点行为不透明,Windows 上可能意外跳入其他卷,需额外校验
FullName.StartsWith(dir.FullName)
跨平台注意:.NET Core/.NET 5+ 的路径分隔符与大小写敏感性
在 Linux/macOS 上,Directory.GetFiles 和 EnumerateFiles 默认区分大小写,且只认正斜杠 / 或系统原生分隔符(Path.DirectorySeparatorChar)。硬写反斜杠 \ 在非 Windows 平台可能静默失败或返回空:
- 始终用
Path.Combine("folder", "sub")拼路径,别手拼字符串 - 过滤时若需忽略大小写,得自己用
StringComparer.OrdinalIgnoreCase做二次筛选,API 不提供该选项 - Docker 容器内挂载 Windows 主机目录时,路径大小写行为取决于挂载方式(如
case-sensitive: false),实测可能和本地 Linux 表现不一致
Directory.EnumerateFiles 加 try/catch 处理权限异常就够了。真要按时间范围筛选,别硬塞在枚举里,先取路径再用 FileInfo 读属性——顺序错了,性能就崩了。










