直接用 seekg(0, ios::end) 去算文件大小?这事儿真不靠谱,尤其是在文本模式下或者跨平台的时候。这不仅仅是 bug,而是 C++ 标准对流行为的明确定义——这种“未指定”特性,本身就意味着你不能依赖它。

为什么 seekg(0, ios::end)ifstream 中可能返回错误大小

问题的根源在于文件的打开方式。ifstream 默认以文本模式(ios::in)打开文件,而文本模式下会有一些“看不见”的字符转换:

正确做法:必须用二进制模式打开 + 检查流状态

只有二进制模式才能保证 seekgtellg 映射到真实的字节偏移。操作路径其实很清晰:

一段标准代码示例:

std::ifstream file("input.txt", std::ios::binary);
if (!file.is_open()) return -1;
file.seekg(0, std::ios::end);
if (!file.good()) return -1; // seek 失败,比如文件不可寻址(管道、stdin)
std::streampos size = file.tellg();
file.seekg(0); // 重置读位置

更健壮的替代方案:绕过流,用系统 API

如果你的目标只是获取文件大小,而不是后续用同一个 ifstream 读取内容,那么推荐直接使用系统原生接口,彻底避开流模式的陷阱:

C++17 示例:

std::error_code ec;
auto size = std::filesystem::file_size("input.txt", ec);
if (ec) { /* 处理错误 */ }

常见误用与静默陷阱

下面这些写法看起来简洁,实际隐患很大:

一句话总结:真正安全的文件大小获取,从来不是“一行代码的事”。取决于你是否愿意接受文本模式的不确定性——如果必须用流,就老老实实开二进制模式并检查每一步;如果只是要大小,filesystemstat 更直接、更可移植。

本文转载于:https://www.php.cn/faq/2317192.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。