




必须加 std::ios::binary,否则Windows下会将\r\n转为\n并可能因\x1A提前截断,Linux虽影响小但跨平台需统一;不加则读取字节数与文件不符。
直接用 std::ifstream 以 std::ios::binary 模式打开,配合 read() 和 gcount() 才能正确读取二进制数据;默认文本模式会破坏 \x00 和换行符,千万别跳过 binary 标志。
std::ios::binary?Windows 下文本模式会把 \r\n 自动转成单个 \n,还会把遇到的 \x1A(EOF 符)提前截断;Linux 虽影响小,但跨平台代码必须统一行为。不加这个标志,读出来的字节数和原始文件对不上是常态。
std::ifstream ifs("data.bin"); → 文本模式,危险std::ifstream ifs("data.bin", std::ios::binary); → 正确起点std::ofstream ofs("out.bin", std::ios::binary);
read() 怎么用才不丢数据?read() 不保证一次读完全部内容,它只按请求长度尝试读,并通过 gcount() 返回实际字节数。尤其在从管道、网络流或某些文件系统读时,容易少读。
seekg(0, std::ios::end); + tellg() 获取真实大小std::vector buf(size); )ifs.read(buf.data(), size); 后立刻检查:if (ifs.gcount() != size) { /* 错误处理 */ }
!ifs.eof() 判断是否读完——它只在尝试读失败后才置位可以直接 read() 进结构体变量,但前提是该类型是标准布局(standard-layout)、无虚函数、无非平凡构造/析构——也就是典型的 C 风格 struct。否则行为未定义。
立即学习“C++免费学习笔记(深入)”;
struct Header {
uint32_t magic;
uint16_t version;
uint8_t flags;
}; // ✅ 可直接 read
Header h;
ifs.read(reinterpret_cast>(&h), sizeof(h));
if (ifs.gcount() != sizeof(h)) { / 失败 */ }
ntohl())#pragma pack(1) 或 [[gnu::packed]] 控制对齐,否则 sizeof(Header) ≠ 实际磁盘布局std::string 或 std::vector 成员直接 read() —— 它们内部指针无效最常被忽略的一点:读完记得检查 ifs.good() 或至少 ifs.fail(),而不是只看 gcount()。有些错误(比如权限不足)会导致 gcount() 为 0,但 failbit 已
