必须先用 exists() 或 status() 检查路径存在再调用 is_directory(),否则抛 filesystem_error;对符号链接需用 symlink_status() 显式判断其自身类型;跨平台应统一用 status() 并检查 type(),避免异常和平台差异。

用 std::filesystem::is_directory 前必须确认路径存在
直接对不存在的路径调用 std::filesystem::is_directory 会抛出 std::filesystem::filesystem_error 异常,而不是返回 false。这不是“判断失败”,而是“操作非法”。
- 务必先用
std::filesystem::exists(path)检查路径是否存在 - 或用
std::filesystem::status(path)一次性获取状态(它对不存在路径返回file_status(file_type::not_found)) - 若不捕获异常且路径不存在,程序将终止(除非编译时定义了
_HAS_EXCEPTIONS=0,但此时行为未定义)
std::filesystem::is_directory 对符号链接的处理需显式指定
默认情况下,std::filesystem::is_directory(path) 会解引用符号链接(即检查它指向的目标),而不是检查链接本身是否为目录。这和 ls -l 中看到的 d 标志不一致。
- 要检查符号链接自身类型(即是否是“目录类型的链接”),得用
std::filesystem::is_directory(std::filesystem::symlink_status(path)) -
status()和symlink_status()的区别:前者跟随链接,后者只读链接元数据 - 常见误写:
is_directory(symlink_status(path).type())—— 错,is_directory接收的是path或file_status,不是file_type
Windows 下注意路径分隔符和权限导致的 filesystem_error
在 Windows 上,即使路径存在,is_directory 也可能因权限不足或路径含保留名(如 AUX、CON)而失败,错误码通常是 access_denied 或 not_supported。
- 不要假设
exists() == true就能安全调用is_directory() - 建议统一用
std::filesystem::status(path)并检查返回值:auto s = status(path);
if (s.type() == file_type::directory) { /* 是目录 */ }
else if (s.type() == file_type::regular) { /* 是文件 */ } - 避免硬编码
"\\"或"/",用std::filesystem::path构造,它会自动标准化分隔符
C++17 之前没有 std::filesystem,别试图用宏“降级”
有些项目仍用 C++14 或更早标准,看到 __cpp_lib_filesystem >= 201703L 就以为能用,其实还依赖编译器支持和标准库实现(如 libstdc++ 从 GCC 8 开始完整支持,MSVC 从 VS 2017 15.7 起支持)。
立即学习“C++免费学习笔记(深入)”;
- 仅靠
#include不够,还需链接选项:-lstdc++fs(GCC)、/std:c++17+ 启用/D_HAS_FILESYSTEM=1(MSVC) - 跨平台项目若需兼容旧环境,应封装一层 fallback:对 Windows 用
GetFileAttributes,对 POSIX 用stat(),而非强行模拟is_directory - 别写
#ifdef __cpp_lib_filesystem就完事——它只说明头文件存在,不代表函数可用
实际判断逻辑最稳的方式是:先 status(),再查 .type(),全程不抛异常;符号链接行为按需选 status 或 symlink_status;Windows 上永远把权限和设备路径当作潜在失败原因。









