std::filesystem::create_directories是C++17起跨平台创建多级目录的唯一推荐方案,自动补全中间路径且幂等;需传入目录路径(用parent_path()提取),检查返回值并捕获filesystem_error。

std::filesystem::create_directories 是 C++17 的标准方案
直接用 std::filesystem::create_directories,它会递归创建所有不存在的中间目录,不需要自己拆路径或逐级调用。这是目前最可靠、跨平台(MSVC/GCC/Clang 均支持)、且无需第三方依赖的方式。
注意:必须开启 C++17 或更高标准,并链接 stdc++fs(GCC)或启用 /std:c++17(MSVC)。
- Linux/macOS 下编译需加
-lstdc++fs(GCC 9+ 可能已隐式链接,但显式加上更稳妥) - Windows MSVC 2019+ 默认支持,但项目属性里要确认 C++ 语言标准设为 C++17 或以上
- 路径分隔符用正斜杠
/即可,std::filesystem会自动适配平台(Windows 下也认/)
#include <filesystem>
namespace fs = std::filesystem;
int main() {
bool ok = fs::create_directories("a/b/c/d"); // 一次性建好 a → a/b → a/b/c → a/b/c/d
if (!ok) {
// 返回 false 表示路径已存在(不是错误!),不是权限失败
// 真正失败时会抛出 fs::filesystem_error 异常
}
}
为什么不要用 _create_directories(Windows 特有、非标准)
_create_directories 不是 C++ 标准函数,也不是 POSIX 函数,而是某些 Windows SDK 头(如 direct.h)里未公开或已弃用的内部符号,不同 VS 版本行为不一致,GCC/Clang 根本不识别。
- VS2015 中可能存在于
direct.h,但文档未收录,无保证 - VS2019+ 已移除或仅在私有头中,链接时大概率报
LNK2019: unresolved external symbol _create_directories - 即使侥幸链接成功,它也不处理路径中反斜杠转义、Unicode 路径长度限制等现代需求
用它等于把代码锁死在某个旧版 Windows 工具链上,毫无移植性可言。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见失败原因和应对方式
std::filesystem::create_directories 抛异常时,错误类型是 std::filesystem::filesystem_error,.code().value() 可查系统错误码(如 EACCES、ENOTDIR)。
- 父目录是文件而非目录 → 报
ENOTDIR:检查路径中是否有同名文件挡路,比如想建logs/2024/06,但当前已有logs文件(非目录) - 权限不足(尤其 Linux/macOS 的只读挂载点,或 Windows 的受控文件夹)→
EACCES:需提前检查fs::status(path).permissions(),或捕获异常后提示用户 - 路径含非法字符或超长(Windows MAX_PATH=260)→ 抛
FILENAME_TOO_LONG或INVALID_PARAMETER:用u8"\\?\C:\long\path"前缀绕过(仅 Windows),或改用短路径
别依赖返回值判断“是否成功创建”——它返回 true 仅表示**至少一个目录被新建**;若全程路径已存在,它返回 false,但这不是错误。
需要兼容 C++14 或更老标准怎么办
没有标准方案,只能手写递归逻辑 + 平台 API:
- Windows:用
CreateDirectoryW,逐级拆std::wstring路径,每级调一次,遇到ERROR_ALREADY_EXISTS继续 - POSIX:用
mkdir,配合strtok_r或std::string::find_first_of拆/分隔的路径段 - 强烈建议封装成 inline 函数,避免重复逻辑;同时加
#ifdef __cpp_lib_filesystem条件编译,新标准优先走std::filesystem
手写路径拆分容易漏掉根路径(如 /home/user 的 /)、忽略多斜杠(a//b///c)、或在 Windows 下混淆盘符(C:)。这些边界情况,std::filesystem::path 内部都已处理干净。


















