std::filesystem::file_size是C++17获取文件大小的最直接方式,但需先用is_regular_file校验并捕获filesystem_error异常,且不适用于目录、权限不足或路径无效等场景。

file_size 函数能直接获取文件大小,但必须确保路径有效且有读取权限
std::filesystem::file_size 是 C++17 引入的最直接方式,它返回 std::uintmax_t 类型的字节数。但它不是“万能安全调用”——如果传入的是目录、符号链接未解引用、路径不存在或权限不足,会抛出 std::filesystem::filesystem_error 异常。
常见错误现象:terminate called after throwing an instance of 'std::filesystem::filesystem_error',往往因为没捕获异常或误把目录当文件传入。
- 使用前先用
std::filesystem::is_regular_file(path)检查是否为普通文件(跳过目录、socket、设备文件等) - 若路径是符号链接,默认按链接本身算(通常很小),如需目标文件大小,加
std::filesystem::symlink_option::follow - Windows 下注意路径分隔符兼容性:用正斜杠
/或双反斜杠\\,避免裸反斜杠引发编译错误
正确调用 file_size 的最小完整示例
以下代码包含必要头文件、命名空间、异常处理和基础校验:
#include#include int main() { std::filesystem::path p = "data.bin"; try { if (std::filesystem::is_regular_file(p)) { auto size = std::filesystem::file_size(p); std::cout << "Size: " << size << " bytes\n"; } else { std::cout << "Not a regular file\n"; } } catch (const std::filesystem::filesystem_error& ex) { std::cerr << "Filesystem error: " << ex.what() << '\n'; } }
注意:MSVC 19.20+、GCC 8.1+、Clang 7.0+ 才完整支持 std::filesystem;GCC 需链接 -lstdc++fs,Clang 同样需要该链接选项。
立即学习“C++免费学习笔记(深入)”;
替代方案:stat 系统调用(跨 C++ 标准,但平台相关)
如果项目不能用 C++17,或需更底层控制(比如区分逻辑大小与磁盘占用),可用 POSIX stat 或 Windows GetFileSizeEx。但这就失去可移植性,且要手动处理结构体字段。
POSIX 示例关键点:
- 包含
,调用stat(path.c_str(), &sb) - 检查返回值是否为 0(失败返回 -1),再读
sb.st_size -
st_size对普通文件是字节数,对 FIFO/设备可能为 0 或无意义
Windows 示例关键点:
- 包含
,用GetFileAttributes先确认是文件(非目录) - 用
CreateFile+GetFileSizeEx,注意 HANDLE 必须带GENERIC_READ权限 - 返回值是
LARGE_INTEGER,需组合LowPart/HighPart
容易被忽略的细节:硬链接、稀疏文件、挂载点
file_size 返回的是文件的逻辑大小(即 ls -l 显示的 size),不是磁盘实际占用(du)。这对稀疏文件(如某些数据库快照、虚拟机镜像)差异极大——逻辑大小可能是 GB 级,实际占用只有几 MB。
硬链接不影响 file_size 结果,所有链接指向同一 inode,返回相同值;但若路径跨挂载点(比如通过 bind mount 或网络文件系统),file_size 仍能工作,前提是底层 OS 支持并已正确挂载。
真正棘手的是只读文件系统或 NFS 超时场景:异常类型仍是 filesystem_error,但错误码可能是 std::errc::operation_not_supported 或 std::errc::timed_out,需针对性判断而非一概吞掉异常。










