该用 create_directories。create_directory 只建最后一级且要求父目录存在,create_directories 才等价于 mkdir -p 递归创建;不确定上级是否存在时必须用后者。

create_directory 和 create_directories 到底该用哪个?
想建 /a/b/c 却只调 create_directory("a/b/c"),结果返回 false——这不是 bug,是函数设计如此。create_directory 只建最后一级,且要求父目录 /a/b 必须已存在;create_directories 才是真正等价于 mkdir -p 的递归创建接口。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 明确知道父路径已存在(比如在
std::filesystem::temp_directory_path()下建子目录),用create_directory - 不确定上级是否存在、或路径来自用户输入/配置,一律用
create_directories - 两个函数都返回
bool,不检查返回值就等于放弃错误反馈:权限拒绝、路径含非法字符(如 Windows 下的:、|)、磁盘满等都会失败 - 编译需加
-std=c++17;GCC 9 以前版本还需链接-lstdc++fs
remove 和 remove_all 删除行为差异极大
remove 不是“删目录”,它只删文件或空目录;对非空目录直接返回 0(即没删任何东西),不报错也不递归。很多人卡在这儿,以为函数失效,其实是语义理解偏差。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 删单个空目录或文件:
remove("path") - 删整个目录树(含子目录、所有文件):
remove_all("path")—— 这才是rm -rf的 C++ 对应物 - 两者都返回
uintmax_t(删除项数),0表示“什么都没删”,常见于路径不存在、无权限、或目标被占用 -
remove_all不进回收站,不可逆;调试时建议先用is_empty或recursive_directory_iterator预览内容
recursive_directory_iterator 不是删除工具,别边遍历边删
看到名字带 “recursive”,容易误以为它能自动删子目录。其实它只是只读遍历器,类似 Python 的 os.walk,本身不修改文件系统。强行在循环里对 entry.path() 调 remove,大概率触发未定义行为:迭代器失效、路径访问冲突、甚至程序崩溃。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 遍历用
recursive_directory_iterator,删除用remove_all—— 职责分离,安全可靠 - 若真需按条件删(比如只删 .tmp 文件),先收集路径到容器,再逆序遍历删除(避免删了父目录后子项路径失效)
- 每次解引用或自增迭代器(
++it)都可能抛异常(如权限不足、路径被移除),try/catch必须包在循环体内,不能只包整个for外层
路径拼接和类型判断必须用 fs::path
直接传 const char* 给 create_directories 虽然能编译,但隐式转换易出错;跨平台时路径分隔符(/ vs \)也由 fs::path 自动处理。不用 fs::path,等于放弃库的设计优势。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 统一用
fs::path构造和拼接:例如fs::path p = "/home"; p /= "user"; p /= "docs.txt" - 用
p.filename()、p.stem()、p.extension()安全提取组件,别用字符串find_last_of("/")手撕 - 判断前先确认存在:
if (fs::exists(p) && fs::is_directory(p)) { ... },否则is_directory对不存在路径返回false,不是报错 -
fs::path对象可直接流输出、比较、赋值,移动构造后原对象变为空路径(p1 = std::move(p2)后p2为空)
recursive_directory_iterator 在遍历时遇到不可访问项会抛 filesystem_error,而 fs::path 移动后原变量失效,这两点在真实项目中极易引发静默故障。


















