必须显式指定std::ios::binary模式,否则windows下会自动转换换行符;仅pod类型安全;需手动处理数组长度、字节序、对齐及错误检查。

用 std::ofstream 以 binary 模式写入数组
直接调用 write() 方法,把数组首地址和总字节数传进去即可。关键不是“怎么存”,而是“别漏掉 std::ios::binary”——缺了它,Windows 下会把 \x0A 自动转成 \x0D\x0A,数据就错了。
-
std::ofstream file("data.dat", std::ios::binary);必须显式加std::ios::binary - 数组类型是
int、double等 POD 类型才安全;含指针或虚函数的类不能直接 dump - 写入长度必须是
sizeof(元素类型) * 元素个数,不能只写元素个数 - 示例:
int arr[] = {1, 2, 3, 4, 5}; std::ofstream f("data.dat", std::ios::binary); f.write(reinterpret_cast<const char>(arr), sizeof(arr));</const>
写入前确认数组大小是否固定或可推导
如果数组是栈上定义的(如 int arr[10]),sizeof(arr) 可用;但如果是 int* arr = new int[n],就得自己记 n,否则文件里没长度信息,读的时候无法还原。
- 二进制文件本身不存元数据,
write()只管写裸字节 - 常见做法:先写一个
size_t n表示元素个数,再写数组内容,读时先读n再分配内存 - 跨平台注意:
size_t在 32/64 位系统上大小不同,若需兼容,改用uint32_t或uint64_t
写入后务必检查 fail() 或 bad()
磁盘满、路径无权限、父目录不存在都会导致写入静默失败——write() 不抛异常,也不返回成功与否,全靠流状态位判断。
- 写完立即检查:
if (!file.good()) { /* 处理错误 */ } -
fail()表示格式或逻辑错误(如写入前文件不可写),bad()表示底层 I/O 失败(如磁盘故障) - 别依赖
is_open():它只说明文件曾打开成功,不代表后续写操作有效
注意字节序和对齐,尤其跨平台或跨语言读取时
C++ 默认按本机字节序(通常是小端)写入,结构体还可能因编译器填充而多出空字节。如果 Python 或 C# 要读这个 .dat,得确保双方对字段顺序、大小、对齐方式完全一致。
- 用
#pragma pack(1)或[[gnu::packed]]防止结构体填充(仅限 POD) - 数值类型建议统一用固定宽度整型(
int32_t、float),避免int在不同平台长度不同 - 如果目标平台字节序不同(比如嵌入式大端设备),写入前要手动翻转字节,用
htons()/htonl()或std::byteswap(C++23)
实际写入时最常被忽略的是:没关文件流就退出程序,导致缓冲区未刷新,文件为空或截断;或者忘了在读端用同样的类型和顺序解析——二进制文件不会告诉你里面存的是什么。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











