源分发确定性执行服务,采用固定依赖。仅在带有签名审批制品(ClawShield模式)时运行,并产生可验证的输出...
std::filesystem::file_size是标准跨平台获取文件大小的方式,但仅适用于普通文件,需先用is_regular_file检查类型并处理异常,且GCC/Clang需链接-lstdc++fs,返回值必须用std::uintmax_t接收。

std::filesystem::file_size 是当前最直接、标准且跨平台的获取方式,但必须配合类型检查和异常处理,否则极易在目录、符号链接或权限不足时崩溃或返回误导性错误。
为什么 file_size 会抛出 “No such file or directory” 却文件明明存在
这不是路径写错了,而是你传入的是目录、符号链接(未解引用)、挂载点或权限受限的路径。file_size 只接受普通文件(regular_file),对目录默认抛 std::filesystem::filesystem_error,错误信息常被误读为“文件不存在”。
- 必须先调用
std::filesystem::is_regular_file(path)做前置判断 - 若需区分符号链接本身和其目标,改用
std::filesystem::symlink_file_size(path) - 权限问题(如
operation_not_permitted)不能靠 exists() 预检——exists()成功不代表file_size()能读元数据
编译与链接:GCC/Clang 下不加 -lstdc++fs 就会链接失败
MSVC 19.20+ 默认支持,但 GCC 8.1+ 和 Clang 7.0+ 需显式链接标准库扩展:-lstdc++fs。漏掉它会导致类似 undefined reference to 'std::filesystem::file_size' 的链接错误。
- 使用 CMake 时,在
target_link_libraries()中追加stdc++fs - Clang 同样需要该链接项,仅加
-std=c++17不够 - 某些旧版 MinGW 可能不提供
std::filesystem,此时应回退到stat()或fopen+fseek/ftell
返回值是 std::uintmax_t,别用 int 或 size_t 接收
大文件(如 >4 GiB)在 32 位环境或某些平台下,size_t 可能截断;int 更是完全不可靠。std::uintmax_t 是唯一保证不溢出的标准类型,最大可表示约 16 EiB。
- 不要写
auto size = ...; int s = size;—— 隐式截断无警告 - 打印时用
std::cout 即可,流操作符已重载支持uintmax_t - 若需转为
size_t(例如传给std::string::reserve()),必须显式检查是否溢出:if (size > SIZE_MAX) throw std::runtime_error("file too large");
替代方案:当 std::filesystem 不可用时,stat() 和 ifstream::tellg() 怎么选
stat()(POSIX)性能最高、一次系统调用,但 Windows 原生不支持(MinGW 可用);ifstream 方案可移植但有陷阱:用 seekg(0, std::ios::end) + tellg() 前,必须以 std::ios::binary 模式打开,否则文本模式下换行符处理会导致结果偏小。
-
stat():Linux/macOS 优先,包含,检查sb.st_mode & S_IFREG确认普通文件 -
ifstream:兼容 C++11,但tellg()在某些文件系统(如 FAT32)或网络挂载卷上可能返回 -1,需判空 - 二者都不处理符号链接自动解引用问题,
file_size()的语义更清晰
实际项目里最容易被忽略的,是把 file_size() 当作“安全函数”直接调用——它既不检查文件类型,也不静默吞错。只要路径不是普通文件,就一定抛异常。这个行为不是缺陷,而是设计意图:强制你面对文件系统的复杂性,而不是假装所有路径都等价。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










