std::filesystem::file_size 是 C++17 起最直接可靠判断文件是否为空的方式,通过检查返回字节数是否为 0;它不依赖读权限,但需路径存在且为常规文件,否则抛 filesystem_error。

用 std::filesystem::file_size 最直接可靠
判断文件是否为空,本质是看其字节长度是否为 0。C++17 起标准库提供了 std::filesystem::file_size,它能准确返回文件大小(单位字节),且对空文件、符号链接、权限受限等情况有明确定义行为。
常见错误是先用 std::ifstream 打开再 peek() 或 eof() 判断——这在文件无读权限、被其他进程独占锁住时会失败或阻塞,而 file_size 只需路径可访问(不依赖读权限)。
- 必须包含头文件:
#include <filesystem></filesystem>,并链接-lstdc++fs(GCC)或启用 C++17(MSVC 默认支持) - 路径需为有效且存在(可用
std::filesystem::exists()预检) - 若路径指向目录,
file_size抛出std::filesystem::filesystem_error,不是返回 0 - 示例:
try { if (std::filesystem::file_size("data.txt") == 0) { // 是空文件 } } catch (const std::filesystem::filesystem_error& e) { // 文件不存在、是目录、或权限不足等 }
兼容 C++11 的 fallback:用 stat 系统调用
若项目不能用 C++17,stat 是最广泛兼容的方案。它不依赖 STL 版本,但需注意跨平台写法。
Windows 下用 _stat64(或 _stati64),Linux/macOS 用 stat;两者结构体字段名一致(如 st_size),但头文件和函数名不同。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- Linux/macOS:
#include <sys></sys>,调用stat("path", &buf) - Windows:
#include <sys></sys>,调用_stat64("path", &buf) - 检查前务必确认
stat返回 0(成功),否则buf.st_size未定义 -
buf.st_size对常规文件是字节数;对 FIFO/设备文件可能为 0,但不代表“空”,需结合buf.st_mode判断类型
为什么不用 ifstream::tellg() + seekg()?
有人尝试打开 std::ifstream 后用 seekg(0, std::ios::end) 再 tellg() 获取长度,再 seekg(0) 回头——这在多数情况可行,但隐患明显:
- 文件被其他进程以
FILE_SHARE_READ以外方式打开(如 Windows 上记事本编辑中),ifstream构造失败 - 二进制模式下某些文件系统(如 NFS)可能报告不准确大小
- 对只读文件或权限受限路径,打开即失败,而
file_size或stat可能仍成功 - 额外构造流对象带来开销,且需手动处理异常和状态位(如
failbit)
注意“空文件”的边界情况
所谓“空”,严格指长度为 0 字节。但实际中容易混淆以下情形:
- 文件存在但内容全是空白字符(空格、换行、
\0)——这不是空文件,file_size返回大于 0 - 符号链接指向一个空文件:
file_size默认解析目标(POSIX 行为),若需判断链接自身,得用std::filesystem::symlink_status和file_size配合 - 某些日志轮转工具会创建 0 字节文件作为标记,此时
file_size == 0是有意为之,不是错误
真正要警惕的是:误把“无法获取大小”当作“空”。任何方案都应先确保路径存在且可查,再判断大小是否为 0。

















