标准做法是先调用 std::filesystem::exists(p) 再调用 std::filesystem::is_directory(p),二者缺一不可;需包含头文件 ,链接 -lstdc++fs(gcc/clang),路径应使用 std::filesystem::path 类型。

用 std::filesystem::exists 和 std::filesystem::is_directory 判断路径存在且为目录
标准做法是先确认路径存在,再判断它是不是目录。C++17 起 std::filesystem 是最可靠、跨平台的方式,不用依赖系统 API 或第三方库。
常见错误是只调用 exists 就认为是目录——但文件也返回 true;或者直接用 is_directory 而不检查存在性,遇到不存在路径会抛出 std::filesystem::filesystem_error 异常。
- 必须包含头文件:
#include <filesystem></filesystem>(GCC/Clang 需加-lstdc++fs,MSVC 默认支持) - 推荐写法:先
exists(p),再is_directory(p),避免异常干扰逻辑流 - 路径字符串建议用
std::filesystem::path类型传入,别直接传const char*,否则某些实现可能因编码或斜杠处理出问题
std::filesystem::path p{"./data"};
if (std::filesystem::exists(p) && std::filesystem::is_directory(p)) {
// 安全进入
}
Windows 下用 GetFileAttributesW 判断目录(兼容旧项目)
如果项目不能用 C++17,或需精确控制错误码(比如区分“拒绝访问”和“路径不存在”),Windows 原生 API 仍是实用选择。
GetFileAttributesW 返回值为 INVALID_FILE_ATTRIBUTES 表示失败,此时要调用 GetLastError() 进一步判断;若成功,则检查是否含 FILE_ATTRIBUTE_DIRECTORY 标志。
- 必须用宽字符路径(
L"./logs"),传char*会导致中文路径乱码或返回 -1 - 注意:符号链接本身可能有
FILE_ATTRIBUTE_DIRECTORY,但目标不是目录——如需解引用,得额外调用GetFinalPathNameByHandle - 该函数不支持 UNC 路径中的相对部分(如
\servershare.. emp),建议先用std::filesystem::weakly_canonical规范化(如果可用)
Linux/macOS 下用 stat 检查 st_mode 的 S_IFDIR 位
POSIX 系统下,stat() 是最底层也最通用的方法,没有 C++17 依赖,适合嵌入式或精简环境。
关键不是看 stat 是否成功,而是成功后从 st_mode 中提取类型信息:用位与 S_IFMT 掩码后再比对 S_IFDIR,不能直接比较 st_mode == S_IFDIR——因为权限位也混在其中。
- 路径传
char*即可,但需确保编码为 UTF-8(尤其含中文时),否则stat可能返回ENOENT -
stat对符号链接默认不解引用;如需跟随链接,改用lstat,再手动readlink + stat - 注意
errno在成功时不会清零,判断失败必须先置零或检查返回值是否为 -1
struct stat sb;
if (stat("./config", &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFDIR) {
// 是目录
}
容易被忽略的边界情况:权限不足、挂载点、空路径
很多代码在开发机上跑通,上线就失败,往往栽在这几类场景里。
- 路径存在但无执行权限(
x位):Linux/macOS 下无法进入目录,is_directory仍返回true,但后续opendir或遍历会失败 - 挂载点未就绪:NFS/Samba 目录可能
exists返回true,但is_directory抛异常或卡住,建议加超时或设std::filesystem::status替代 - 空字符串或仅含空格的路径:
std::filesystem::path构造后可能变成当前目录,exists返回true,但显然不是你想要的“指定目录” - Windows 驱动器根目录(如
"C:\")在某些旧版 MinGW 下is_directory可能返回false,建议统一用status().type() == std::filesystem::file_type::directory
真正稳的判断,从来不是单次调用,而是结合上下文做防护:路径预处理、权限预检、失败后降级策略(比如 fallback 到 mkdir 并捕获 EEXIST)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











