std::filesystem::create_directories 有时不创建目录的最常见原因是路径含相对路径且当前工作目录不符,或父目录权限不足;它仅在至少创建一个新目录时返回true,否则静默返回false。

为什么 std::filesystem::create_directories 有时不创建任何目录?
最常见原因是路径中包含相对路径且当前工作目录不在预期位置,或者父目录权限不足。该函数不会报错但返回 false,容易误以为“成功跳过”。它只在**至少创建了一个新目录**时才返回 true;如果所有目录已存在,就安静地返回 false。
使用前务必确认:
-
std::filesystem::exists检查路径是否已存在(避免误判失败) - 路径末尾不要加斜杠(
"path/"可能被解析为文件而非目录) - 确保对父路径有写权限(尤其在 Linux/macOS 的受限目录下)
create_directories 和 create_directory 的关键区别
create_directory 只建最后一级,要求父目录必须已存在;create_directories 是递归建全路径——这才是“多级目录”的正确选择。
示例对比:
立即学习“C++免费学习笔记(深入)”;
std::filesystem::create_directory("a/b"); // 失败:a 不存在
std::filesystem::create_directories("a/b"); // 成功:自动建 a,再建 b
注意:create_directories 对已存在的中间目录不做任何操作,也不会覆盖同名文件——如果 "a" 已是一个普通文件,调用会抛出 std::filesystem::filesystem_error。
Windows 路径字符串要加 L 前缀吗?
不需要。C++17 std::filesystem 接口统一接受 std::string 或 std::wstring,但底层行为取决于编译器和标准库实现。MSVC 默认用 UTF-16,Clang/GCC 通常用 UTF-8。
安全做法是统一用 std::string 并确保源文件保存为 UTF-8(无 BOM):
std::filesystem::create_directories("data/logs/2024/06");
若路径含中文等 Unicode 字符,且你用的是 MSVC + std::string,需确保控制台或环境支持 UTF-8(例如调用 SetConsoleOutputCP(CP_UTF8)),否则可能静默失败或生成乱码目录名。
错误处理不能只靠 try/catch,还要检查返回值
该函数设计为“不抛异常”是常态,仅在严重系统错误(如磁盘满、权限拒绝)时抛 std::filesystem::filesystem_error。日常场景如“目录已存在”“路径为空”“上级只读”,都通过返回值体现。
典型健壮写法:
namespace fs = std::filesystem;
fs::path p = "cache/images/thumbnails";
if (!fs::create_directories(p)) {
if (!fs::is_directory(p)) {
throw std::runtime_error("Failed to create directories: " + p.string());
}
// 目录已存在,继续
}
这里两次检查:先看 create_directories 返回值,再用 is_directory 确认它真是个目录——防止同名文件阻塞后续操作。
跨平台项目里,Linux 下的挂载点、macOS 的 APFS 快照、Windows 的符号链接都可能导致看似成功的调用实际未生效,所以最终验证比依赖返回值更可靠。











