必须显式指定std::ios::binary模式,否则Windows下'\n'会被转为"\r\n"导致数据错位;写二进制必须用write()配合reinterpret_cast<const char*>和sizeof,禁用<<操作符,并注意字节序、结构体对齐及运行时状态检查。

用 std::ofstream 以 std::ios::binary 模式打开文件
不加 std::ios::binary,写入的 char 值可能被误解释为换行符(如 '\n' 被转成 "\r\n"),尤其在 Windows 上导致数据错位。必须显式指定二进制模式:
std::ofstream file("data.bin", std::ios::binary);
if (!file.is_open()) {
// 处理错误
}- 不能用
operator<<写原始字节——它会格式化输出(比如把0x0A当成换行) - 必须用
write()成员函数,传入指针和字节数 - 文件路径中避免中文或空格(尤其在某些编译器/运行环境里容易静默失败)
用 write() 写入原始内存块
write() 只认 const char* 和 std::streamsize,所以任何类型都要先取地址并 reinterpret_cast:
int x = 0x12345678; file.write(reinterpret_cast<const char*>(&x), sizeof(x));
- 结构体可直接写,但要注意:含指针、虚函数、非 POD 类型会出问题;建议只用于简单 struct(如
struct Point { int x, y; };) - 数组写入时别漏掉
sizeof(arr)—— 对int arr[10]有效,对int* arr无效(此时得手动传长度 ×sizeof(int)) - 写入前确保对象生命周期未结束(比如不要写局部变量的地址,而该变量已返回)
注意字节序和对齐差异
你写进去的 int 在另一台机器上读出来可能是反的——因为 x86 是小端,ARM 可能是大端;结构体 padding 也因编译器和平台而异。
- 跨平台传输时,别直接写原生
int,改用固定宽度类型如uint32_t,并约定字节序(比如总是网络序:htonl(x)再写) - 结构体加
#pragma pack(1)或[[gnu::packed]]可禁用填充,但会降低访问性能,且某些 CPU 不支持非对齐访问 - 调试时用十六进制编辑器(如 HxD、xxd)验证写入内容是否符合预期,比靠“程序没报错”更可靠
关闭前检查 failbit 和 badbit
写入中途磁盘满、权限不足、USB 拔掉等,write() 不会抛异常,也不会自动提示——只设标志位。
立即学习“C++免费学习笔记(深入)”;
file.write(...);
if (file.fail()) {
// 写入失败(可能部分成功)
}
file.close();
if (file.fail()) {
// close 失败,说明 flush 或 sync 出问题
}- 别只查
is_open()—— 它只表示打开成功,不保证后续写入正常 -
failbit表示格式或逻辑错误(如 write 长度为负),badbit表示系统级错误(如磁盘 I/O 失败) - 如果要求强一致性(比如关键配置),考虑
file.flush()后再检查状态
二进制写入真正麻烦的不是语法,而是隐式依赖:平台字节序、内存布局、I/O 状态是否被认真检查。哪怕只写一个 float,也可能在不同机器上读出 NaN。


















