Directory.CreateDirectory 不会静默失败,但已存在时直接返回现有 DirectoryInfo 而不报错;它幂等、自动递归创建父目录、支持 Unicode,权限不足抛 UnauthorizedAccessException,路径非法抛 ArgumentException 或 IOException。

Directory.CreateDirectory 会静默失败吗?
不会,但容易误判成功——Directory.CreateDirectory 在目标路径已存在时**不报错、不抛异常、直接返回现有 DirectoryInfo 对象**。很多人用它做“创建前判断”,结果逻辑被绕过。
常见错误写法:
if (!Directory.Exists(path)) {
Directory.CreateDirectory(path); // ✅ 看似安全
}
其实没必要:直接调用 Directory.CreateDirectory(path) 就行,它本身是幂等的。多一次 Exists 查询反而增加 IO 开销,且在高并发下可能引发竞态(检查后被别人创建,再创建就冗余)。
- Windows 下路径分隔符用
\或/都可,.NET 内部统一处理 - 路径含中文、空格、emoji 完全没问题,只要文件系统支持(NTFS/FAT32/exFAT 均支持 UTF-16)
- 若父目录不存在,
CreateDirectory会自动递归创建全部中间层级(比如"a\b\c"不存在,它会一并建好a和b)
权限不足时抛什么异常?怎么捕获最准?
典型报错是 UnauthorizedAccessException,但它常和 IOException 混在一起——尤其在 NTFS 权限受限或路径指向只读卷时。
更稳妥的做法是明确区分两类失败:
-
UnauthorizedAccessException:当前进程无权在该位置创建目录(如写入C:\Program Files而未提权) -
IOException:路径非法(含控制字符、长度超 260)、磁盘满、U 盘被拔出等底层 I/O 故障 -
ArgumentException或PathTooLongException:路径字符串本身违规(如含*?等非法字符,或总长度 >32767)
示例健壮写法:
path
跨平台要注意哪些路径陷阱?
.NET Core / .NET 5+ 已基本抹平 Windows/macOS/Linux 差异,但仍有几个硬伤点必须手动处理:
-
DirectorySeparatorChar不等于AltDirectorySeparatorChar:Linux/macOS 只认/,Windows 两者都认,但某些旧 API(如部分 WSL 交互)对\敏感——建议统一用Path.Combine("a", "b", "c")构造路径,别拼字符串 - 根路径写法不同:
"C:\temp"(Win) vs"/tmp"(Unix),用Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)替代硬编码更可靠 - 大小写敏感性:Linux/macOS 默认区分
Logs和logs,Windows 不区分——若代码依赖目录名大小写匹配(如配置查找),需主动 Normalize
验证路径是否合法(不实际创建)可用:
bool isValid = !Path.GetInvalidPathChars().Any(c => path.Contains(c)) &&
path.Length <h3>为什么有时创建了却看不到文件夹?</h3><p>最常见原因是路径末尾带斜杠(如 <code>"logs\"</code>)导致 <code>Directory.CreateDirectory</code> 把它当文件处理;或者路径中混用了正反斜杠又没 Normalize,触发了 UNC 路径解析歧义。</p><p>另一个隐蔽坑:在容器或沙盒环境(如 GitHub Actions、Docker)里,工作目录不是你想象的根目录,<code>"./data"</code> 可能落在只读层。此时 <code>CreateDirectory</code> 表面成功,但实际写入的是临时 overlayfs 层,重启即丢。</p>
- 调试时先打印
Path.GetFullPath(path)确认真实绝对路径 - 用
File.GetAttributes(path)检查返回值是否含FileAttributes.Directory,而非只信“没报错就是成功” - 在 CI/CD 中避免相对路径,优先用
Environment.GetEnvironmentVariable("HOME")或挂载卷的绝对路径
路径构造和权限校验这两步,比创建动作本身更容易出问题。










