必须用二进制模式(std::ios::binary)配合write()写入原始字节,避免文本模式换行符转换;写入前需确保数据类型安全(如用uint8_t而非char)、字节序一致(如htons),禁用std::hex等字符串输出方式。

用 std::ofstream 以二进制模式写入原始字节
直接用文本模式写 "FF" 是字符串,不是字节 0xFF。必须用二进制模式(std::ios::binary)配合 write() 写入原始内存数据。
- 打开文件时务必加
std::ios::binary,否则 Windows 下会把0x0A换成0x0D 0x0A -
write()接收的是const char*和字节数,所以要把数据转成char或unsigned char指针 - 例如写入
0x12, 0x34, 0xAB, 0xCD:先存到std::vector<unsigned char> data = {0x12, 0x34, 0xAB, 0xCD};</unsigned>,再调用file.write(reinterpret_cast<const char>(data.data()), data.size());</const>
写单个字节或小整数时注意类型和字节序
C++ 基本类型(如 int、short)写入前必须明确字节序和大小,否则跨平台读取会错乱。
- 写
uint16_t x = 0x1234;不能直接write(&x, sizeof(x))—— 这写的是本机字节序(通常是小端),如果目标系统是大端就解析错误 - 若需固定格式(如网络序),用
htons()/htonl()转换:uint16_t net_x = htons(x); file.write(reinterpret_cast<const char>(&net_x), sizeof(net_x));</const> - 写单字节(
uint8_t)不用考虑字节序,但别用char—— 它可能是有符号的,0xFF会被解释成-1,影响指针转换
避免用 std::hex 流操作符写十六进制字符串
std::hex 输出的是 ASCII 字符串(比如 0xFF 变成三个字节:'F'、'F'、'\n'),不是真正的十六进制字节数据。
- 这种写法适合调试日志或人类可读的 hex dump,不适合写二进制协议、图像、加密密钥等需要原始字节的场景
- 如果误用:
file ,实际写入的是两个字符 <code>'f'和'f'(小写取决于std::uppercase设置),不是单字节0xFF - 想生成 hex 字符串再转字节?那就得先解析字符串(如
"A1B2"→{0xA1, 0xB2}),再写入 —— 多此一举,直接构造字节数组更可靠
写入后记得检查 failbit 和 badbit
二进制写入失败往往不报异常(默认关闭异常),靠状态位判断,容易被忽略。
立即学习“C++免费学习笔记(深入)”;
- 每次
write()后建议检查:if (!file) { /* error */ },它等价于file.fail() || file.bad() -
failbit可能因磁盘满、权限不足触发;badbit更严重,比如底层 write() 系统调用返回 -1 - 不要只依赖
is_open()—— 文件打开成功不代表后续写入一定成功
真正写 16 进制数据,本质是写字节序列。关键不是“怎么表示十六进制”,而是“怎么把你要的字节准确无误地塞进文件”。字节来源、字节序、写入模式、错误检查,四者缺一不可。漏掉任意一个,文件看起来像,但程序读出来就是错的。


















