用 Directory.Exists
最直接判断目录是否存在
这是 C# 中最常用、最轻量的方式,不抛异常、不依赖权限检查,只查路径是否为有效目录。它返回
true仅当该路径存在且被操作系统识别为目录(而非文件)。
Directory.Exists对不存在的父路径不做递归验证,比如
"C:\a\b\c"不存在,但
"C:\a"也不存在时,它仍返回
false如果路径语法非法(如含
*、
?或过长),会直接返回
false,不会抛
ArgumentException对符号链接或挂载点行为取决于 OS:Windows 下通常跟随链接;Linux/macOS(.NET 6+)默认不跟随,需配合
FileAttributes.ReparsePoint手动处理
需要区分“不存在”和“无访问权限”时用 try/catch
+ Directory.GetAccessControl
单纯
Directory.Exists无法告诉你路径是真不存在,还是因权限不足读不到。比如某目录被 ACL 完全拒绝,它就返回
false,和根本没创建过的目录表现一致。 可尝试调用
Directory.GetAccessControl(path):成功 → 目录存在且可读元数据;抛
UnauthorizedAccessException→ 很可能存在但无权访问;抛
DirectoryNotFoundException→ 基本确定不存在 注意:.NET Core 3.1+ 在非 Windows 系统上,
GetAccessControl可能抛
PlatformNotSupportedException,需先判断
OperatingSystem.IsWindows()不要仅靠
Exception.Message判断错误类型,始终捕获具体异常类型
检查前需要确保路径字符串合法,避免 ArgumentException
传给
Directory.Exists的路径若含非法字符、为空或全是空白,.NET 会直接抛
ArgumentException,而不是返回
false—— 这容易让调用方误以为目录“不存在”,实则是参数错了。 用
Path.GetInvalidPathChars()和
Path.GetInvalidFileNameChars()辅助校验(但注意:它们不覆盖所有限制,比如 Windows 路径长度上限 260 字符) 更稳妥的做法是先用
string.IsNullOrWhiteSpace(path)排除空值,再用
Path.IsPathRooted(path)判断是否为绝对路径(相对路径在不同工作目录下结果不稳定) 若路径来自用户输入或配置文件,建议用
Path.GetFullPath(path)标准化后再检查,它会自动展开
".."、
"."并检测非法结构
并发场景下 Exists
返回 true
后立即操作仍可能失败
这是一个经典的时间窗口问题:
Directory.Exists返回
true只代表“此刻存在”,但下一毫秒它可能被其他进程删除或改名。后续的
Directory.Delete或
Directory.CreateDirectory仍可能抛异常。 不要写“先判断再操作”的条件逻辑,例如:
if (Directory.Exists(p)) Directory.Delete(p);—— 应直接
try { Directory.Delete(p); } catch (DirectoryNotFoundException) { }
创建目录同理:优先用 Directory.CreateDirectory(path),它本身是幂等的(目录已存在时不报错) 若必须原子性判断+操作(如日志归档前确认备份目录就绪),考虑用文件系统监视器(
FileSystemWatcher)或加锁机制,但代价高,多数情况没必要
实际编码中,95% 的场景用
Directory.Exists就够了,但得记住它不处理权限、不校验参数、也不保证后续操作安全——这些边界恰恰是线上出问题最多的地方。
