c++oding="utf-8" ?>
createdirectory(windows)、mkdir(linux/macos)和std::filesystem::create_directories(跨平台)是创建目录的三种主流方式,分别对应原生api、posix系统调用和现代c++标准库方案,各需注意路径存在性、权限掩码、编码及编译配置等细节。

Windows 下用 CreateDirectory 创建单层文件夹
直接调用 Win32 API 是最轻量、最可靠的方式,不依赖第三方库,也不需要 C++17 支持。CreateDirectory 只能创建**最后一级目录**,父路径必须已存在,否则失败。
常见错误现象:CreateDirectory 返回 0,GetLastError() 返回 ERROR_PATH_NOT_FOUND(3)——说明上级路径不存在。
- 使用前确保父路径已存在,或逐级检查并创建
- 路径字符串末尾不要加反斜杠(如
"C:\mydir\"),否则可能被误判为无效路径 - 传入宽字符版本(
CreateDirectoryW)更稳妥,避免 ANSI 编码导致中文路径乱码或失败
示例:
if (!CreateDirectoryW(L"C:\temp\newfolder", nullptr)) {
DWORD err = GetLastError();
if (err == ERROR_PATH_NOT_FOUND) {
// 父目录不存在,需先创建
}
}
跨平台方案:C++17 的 std::filesystem::create_directory
这是目前最推荐的通用做法,但要注意它只建**单层**,和 CreateDirectory 行为一致;真正递归建多级要用 std::filesystem::create_directories。
容易踩的坑:std::filesystem 在 MinGW 或旧版 MSVC(如 VS2015)中默认未完全启用,链接时可能报 undefined reference to 'std::filesystem::...' 。
- MSVC:确保项目设置中启用 C++17(/std:c++17),且运行时库匹配(/MD 或 /MT)
- MinGW-w64:需加编译选项
-lstdc++fs,否则链接失败 - 路径参数统一用
std::filesystem::path构造,避免裸字符串隐式转换出错
示例:
namespace fs = std::filesystem;
if (!fs::create_directories("data/cache/logs")) {
// 失败,可能是权限不足或磁盘满
}
Linux/macOS 下用 mkdir 系统调用
POSIX 环境下,mkdir 是底层事实标准,头文件是 <sys></sys> 和 <sys></sys>。它也只建单层,要递归得自己循环或改用 mkdir -p shell 命令(不推荐)。
关键点在于权限掩码(mode):第二个参数不是随便填的数字,要符合系统 umask 规则,否则可能创建出不可写目录。
- 常用值是
0755(所有者读写执行,组和其他人读+执行) - 务必用八进制字面量(前面加
0),写成755就是十进制,权限全错 - 返回 -1 表示失败,
errno可查具体原因(如EACCES权限拒绝,EEXIST已存在)
示例:
if (mkdir("build/out", 0755) == -1) {
if (errno == EEXIST) {
// 目录已存在,通常可忽略
}
}
为什么不用 system("mkdir -p ...")
看似简单,实际问题密集:无法可靠判断是否成功(system 返回的是 shell 进程退出码,不是 mkdir 本身结果);路径含空格或特殊字符时极易崩;Windows/Linux 命令语法不一致;无权限控制;启动新进程开销大。
更隐蔽的问题是:某些嵌入式或沙盒环境禁用 system,或者 PATH 中没有 mkdir,导致行为不可预测。
- 即使只是临时脚本,也建议优先用
std::filesystem::create_directories或平台原生 API - 若真要调用 shell,至少用
std::quoted(C++20)包裹路径,但依然不解决跨平台和可靠性问题
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











