最直接方式是先用std::filesystem::exists判断路径存在,再用is_directory确认是否为目录;create_directories可安全创建多级目录,返回true表示至少新建一级,false表示全已存在。

用 std::filesystem::exists 判断目录是否存在(C++17)
最直接的方式是调用 std::filesystem::exists 并配合 std::filesystem::is_directory,因为 exists 对文件和目录都返回 true,单靠它无法区分。
常见错误是只判 exists 就认为是目录,结果路径指向一个普通文件时逻辑出错。
- 必须先确认路径存在,再确认它是目录:
namespace fs = std::filesystem; if (fs::exists(path) && fs::is_directory(path)) { /* 是有效目录 */ } - 注意:
path末尾带不带斜杠不影响判断,但若路径字符串为空、含非法字符或权限不足,exists可能抛fs::filesystem_error - Windows 下路径大小写不敏感,Linux 下敏感——跨平台代码别依赖大小写匹配
用 std::filesystem::create_directories 创建多级目录
这是 C++17 标准中唯一推荐的多级创建方式,会逐级创建所有不存在的父目录,已存在的目录会被跳过,不报错。
容易踩的坑是误用 create_directory(只建最后一级),或者在 Windows 下用反斜杠没转义导致编译失败。
立即学习“C++免费学习笔记(深入)”;
-
create_directories返回bool:成功创建至少一级目录返回true;全已存在则返回false,但不算错误 - 路径中使用正斜杠
/安全通用,Windows 也支持;避免裸反斜杠,如需字面量写成"C:\foo\bar"或用原始字符串R"(C:ooar)" - 权限由系统默认 umask 决定,C++ 标准库不提供设置权限的跨平台接口(Linux 下可后续调用
chmod,Windows 需SetSecurityInfo)
没有 C++17 怎么办?退化方案要分平台处理
如果项目卡在 C++11/14,std::filesystem 不可用,就得手动适配:
- Linux/macOS:调用
mkdir -p通过system()(不推荐,有 shell 注入风险),更安全的是循环拆解路径、逐级调用::mkdir(path.c_str(), 0755) - Windows:用
CreateDirectoryA或CreateDirectoryW,需自己分割路径(如用\或/分隔)、按顺序创建;注意宽字符路径要转std::wstring - 第三方替代:Boost.Filesystem(接口几乎一致,但需链接 boost_system)、或轻量封装
dirent.h+stat(仅 Linux)
权限和并发场景下的隐性问题
即使 create_directories 返回 true,也不代表后续一定能写入——可能因父目录权限为 dr-xr-xr-x 导致子目录创建失败(实际抛异常),或多个线程/进程同时创建同一路径引发竞态。
- 典型错误现象:
filesystem_error: No such file or directory,其实是因为中间某级目录存在但不可遍历(缺少执行/x 权限) - 安全做法:创建后立即用
fs::exists+fs::is_writable(需自行实现,标准库无此函数)验证可写性 - 多线程下建议加互斥锁保护整个“检查+创建”流程,或直接容忍
create_directories失败(它本身是幂等的,重复调用无副作用)
路径是否可访问,远不止“存在与否”四个字能概括。权限、编码、挂载状态、符号链接循环……这些在开发机上常被忽略的点,上线后最容易突然冒出来。











