std::filesystem::file_size是C++17获取文件大小最直接方式,但需开启C++17标准、链接-libstdc++fs(GCC),并用try/catch捕获filesystem_error异常,因其对路径不存在、目录、权限不足等情况均抛异常。

用 std::filesystem::file_size 获取文件大小(C++17)
必须开启 C++17 或更高标准,且链接 stdc++fs(GCC 下常见坑)。std::filesystem::file_size 是最直接的方式,但它不处理所有情况——比如路径不存在、是目录、权限不足时会抛出 std::filesystem::filesystem_error。
- 确保编译器支持:Clang 7+、GCC 8+、MSVC 2017 15.7+
- 编译时加
-std=c++17(GCC/Clang),MSVC 默认启用但需确认项目设置 - Linux 下 GCC 需额外链接:
-lstdc++fs;Clang 可能还需-lc++fs - 头文件只需
#include,无需其他宏定义
捕获 filesystem_error 避免程序崩溃
file_size 在遇到无效路径、符号链接断裂、无读权限等情况时一定抛异常,不能忽略。常见错误信息如 "No such file or directory" 或 "Permission denied" 都来自这里。
- 用
try/catch(const std::filesystem::filesystem_error& e)包裹调用 -
e.code().value()可获取系统 errno(如2表示 ENOENT) - 不要只依赖
exists()前置判断——它和file_size之间存在竞态窗口(文件可能被删/改) - 若只需“大小或 -1”,可封装成安全函数:
std::int64_t safe_file_size(const std::filesystem::path& p) {
try {
return static_cast(std::filesystem::file_size(p));
} catch (const std::filesystem::filesystem_error&) {
return -1;
}
}
file_size 对目录、符号链接的行为
它只对常规文件返回字节数;对目录默认抛异常(is_directory(p) 为 true 时);对符号链接则默认解析目标(即返回链接指向的文件大小),除非传入 std::filesystem::symlink_option::nofollow。
- 想跳过符号链接本身(不解析目标)?写成:
file_size(p, std::filesystem::symlink_option::nofollow) - 检查是否为常规文件再调用更稳妥:
is_regular_file(p),注意它也抛异常,需同样 try/catch - 目录没有“大小”概念,POSIX 中
st_size对目录无意义;file_size不提供目录占用磁盘空间的接口(那得用du或递归统计)
替代方案:用 stat 系统调用(跨 C++ 标准)
如果无法用 C++17,或需极致控制(比如避免异常、兼容旧环境),回退到 POSIX stat 或 Windows GetFileSizeEx 更可靠。但要注意:C++ 标准库的 file_size 内部通常就调这些,只是封装了错误路径。
立即学习“C++免费学习笔记(深入)”;
- Linux/macOS:
struct stat buf; if (stat(path.c_str(), &buf) == 0) size = buf.st_size; - Windows:
WIN32_FILE_ATTRIBUTE_DATA attr; if (GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &attr)) size = (static_cast(attr.nFileSizeHigh) - 这两种方式都不抛 C++ 异常,错误靠返回值判断,更适合嵌入式或性能敏感场景
file_size 看似简单,但异常路径、符号链接策略、跨平台链接选项这三点最容易漏掉——尤其在 CI 环境里 GCC 没加 -lstdc++fs 会导致链接失败,而本地开发可能因为静态链接侥幸通过。










