news 2026/4/3 6:12:14

C++:写二进制文件(附带源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++:写二进制文件(附带源码)

一、项目背景详细介绍

在前面的内容中,我们已经系统讲解了如何使用 C++ 读取二进制文件。在实际工程中,“读”和“写”永远是成对出现的能力,尤其是在涉及二进制数据时更是如此。

二进制文件的“写”操作,广泛存在于以下场景中:

  • 数据采集程序将结果保存为二进制文件

  • 游戏存档系统

  • 音视频数据编码输出

  • 网络抓包或缓存落盘

  • 结构化数据的高效持久化

  • 科学计算结果保存

相比文本文件,二进制文件具有:

  • 存储紧凑

  • 写入速度快

  • 精度无损

  • 结构完全由程序控制

但同时也意味着:

程序必须对写入的每一个字节负责

因此,正确、严谨地写二进制文件,是 C++ 工程能力中非常关键的一环


二、项目需求详细介绍

2.1 功能性需求

本项目需要实现以下功能:

  1. 以二进制模式创建/打开文件

  2. 向文件中写入二进制数据

  3. 支持写入:

    • 基本类型

    • 结构体

    • 字节数组 / 缓冲区

  4. 保证写入数据完整、顺序正确

  5. 提供简单示例用于验证


2.2 非功能性需求

  • 仅使用 C++ 标准库

  • 不依赖任何第三方库

  • 代码结构清晰、注释完整

  • 行为可预测、无未定义行为

  • 跨平台(Windows / Linux / macOS)


2.3 二进制写入的基本原则

  • 必须使用std::ios::binary

  • 必须明确写入字节数

  • 不做任何字符编码转换

  • 不自动追加换行符


三、相关技术详细介绍

3.1 C++ 二进制文件写入方式

使用std::ofstream并指定二进制模式:

std::ofstream ofs("data.bin", std::ios::binary);


3.2 二进制写入核心接口

ofs.write(const char* buffer, std::streamsize size);

说明:

  • buffer:数据起始地址

  • size:写入字节数

  • 不关心数据内容


3.3 写入结构体的注意事项

直接写结构体需满足:

  • POD 类型(Plain Old Data)

  • 无指针成员

  • 对齐方式一致

  • 字节序一致


3.4 文件覆盖与追加

  • 默认:覆盖写入

  • 追加写入:

std::ios::binary | std::ios::app


四、实现思路详细介绍

本示例通过三个层次演示二进制写入:

  1. 写入基本数据类型

  2. 写入结构体

  3. 写入字节数组(缓冲区)

并将其拆分为清晰、可复用的函数,以便在工程中直接使用。


五、完整实现代码

/******************************************************** * 文件名:write_binary.cpp * 功能:使用 C++ 写入二进制文件 * 说明: * 1. 演示二进制文件写入的基本方法 * 2. 支持写入基本类型、结构体和缓冲区 * 3. 仅使用 C++ 标准库 ********************************************************/ #include <iostream> #include <fstream> #include <vector> #include <cstdint> /** * @brief 示例结构体(POD 类型) * 注意:实际工程中需考虑对齐和字节序问题 */ struct DataBlock { int32_t id; double value; char flag; }; /** * @brief 写入基本数据类型到二进制文件 * @param fileName 文件路径 * @return true 成功 * @return false 失败 */ bool writeBasicTypes(const std::string& fileName) { std::ofstream ofs(fileName, std::ios::binary); if (!ofs.is_open()) { return false; } int32_t number = 12345; double pi = 3.1415926; char ch = 'A'; // 按字节写入基本类型 ofs.write(reinterpret_cast<const char*>(&number), sizeof(number)); ofs.write(reinterpret_cast<const char*>(&pi), sizeof(pi)); ofs.write(reinterpret_cast<const char*>(&ch), sizeof(ch)); ofs.close(); return true; } /** * @brief 写入结构体到二进制文件 * @param fileName 文件路径 * @param data 要写入的结构体 * @return true 成功 * @return false 失败 */ bool writeStruct(const std::string& fileName, const DataBlock& data) { std::ofstream ofs(fileName, std::ios::binary); if (!ofs.is_open()) { return false; } // 直接写入结构体的内存布局 ofs.write( reinterpret_cast<const char*>(&data), sizeof(DataBlock)); ofs.close(); return true; } /** * @brief 写入字节缓冲区到二进制文件 * @param fileName 文件路径 * @param buffer 字节数据 * @return true 成功 * @return false 失败 */ bool writeBuffer( const std::string& fileName, const std::vector<char>& buffer) { std::ofstream ofs(fileName, std::ios::binary); if (!ofs.is_open()) { return false; } // 写入整个缓冲区 ofs.write(buffer.data(), static_cast<std::streamsize>(buffer.size())); ofs.close(); return true; } int main() { // ================= 示例 1:写入基本类型 ================= if (writeBasicTypes("basic.bin")) { std::cout << "成功写入基本类型数据到 basic.bin" << std::endl; } else { std::cout << "写入 basic.bin 失败" << std::endl; } // ================= 示例 2:写入结构体 ================= DataBlock data{}; data.id = 1; data.value = 99.5; data.flag = 'Y'; if (writeStruct("struct.bin", data)) { std::cout << "成功写入结构体到 struct.bin" << std::endl; } else { std::cout << "写入 struct.bin 失败" << std::endl; } // ================= 示例 3:写入缓冲区 ================= std::vector<char> buffer = { 'H', 'e', 'l', 'l', 'o', '\0' }; if (writeBuffer("buffer.bin", buffer)) { std::cout << "成功写入缓冲区到 buffer.bin" << std::endl; } else { std::cout << "写入 buffer.bin 失败" << std::endl; } return 0; }

六、代码详细解读(仅解读方法作用)

6.1writeBasicTypes

  • 演示如何写入int / double / char等基本类型

  • 每次写入都明确字节大小

  • 常用于固定格式数据文件


6.2writeStruct

  • 直接将结构体内存布局写入文件

  • 写入效率高

  • 要求结构体是 POD 类型


6.3writeBuffer

  • 用于写入任意字节数据

  • 适合网络缓存、文件块写入


6.4main函数

  • 演示三种典型二进制写入方式

  • 可直接配合“读二进制文件”示例进行验证


七、项目详细总结

通过本项目,你已经完整掌握:

  • C++ 二进制文件写入流程

  • ofstream + ios::binary的正确用法

  • 基本类型、结构体、缓冲区的写入方式

  • 二进制数据持久化的工程实践

这部分内容是:

  • 网络协议

  • 音视频处理

  • 游戏存档

  • 高性能计算

基础能力模块


八、项目常见问题及解答

Q1:可以直接写std::string吗?

不推荐。
应写入长度 + 字节内容,避免歧义。


Q2:结构体写入安全吗?

仅在同平台、同编译器、同对齐规则下安全。


Q3:写入失败如何检测?

可检查:

ofs.good()


Q4:能否边写边读?

可以,但需使用fstream并控制文件指针。


九、扩展方向与性能优化

9.1 二进制文件追加写入

9.2 大文件分块写入

9.3 跨平台二进制格式设计

9.4 二进制序列化 / 反序列化框架

9.5 内存映射文件(mmap / CreateFileMapping)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/13 18:59:48

C++:用WriteFile函数写文件(附带源码)

一、项目背景详细介绍在 Windows 平台的 C 工程开发中&#xff0c;除了使用 C 标准文件流&#xff08;fstream&#xff09;&#xff0c;我们还经常会直接使用 Windows API 来进行底层文件操作。其中&#xff0c;WriteFile 是 Windows 平台上&#xff1a;最核心、最底层、最常用…

作者头像 李华
网站建设 2026/3/26 21:21:47

如何实现无损输出?unet PNG格式优势实战验证

如何实现无损输出&#xff1f;UNet PNG格式优势实战验证 1. 为什么“无损”在人像卡通化中特别重要&#xff1f; 你有没有试过把一张精心调好的卡通人像发给设计师&#xff0c;结果对方说&#xff1a;“这图边缘有锯齿&#xff0c;头发丝糊成一片&#xff0c;没法用”&#x…

作者头像 李华
网站建设 2026/3/22 21:17:01

Live Avatar issue撰写规范:有效反馈问题的五大要素

Live Avatar issue撰写规范&#xff1a;有效反馈问题的五大要素 1. 为什么问题反馈的质量决定解决速度 你有没有遇到过这样的情况&#xff1a;提交了一个问题&#xff0c;等了几天却只收到一句“请提供更多信息”&#xff1f;或者更糟——问题石沉大海&#xff0c;连个回应都…

作者头像 李华
网站建设 2026/3/21 23:33:17

OpenCore Legacy Patcher焕新指南:让老旧Mac重获新生的实战攻略

OpenCore Legacy Patcher焕新指南&#xff1a;让老旧Mac重获新生的实战攻略 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当你的Mac被苹果官方终止系统更新支持时&#…

作者头像 李华
网站建设 2026/4/2 12:09:11

在线PDF处理工具全攻略:零基础也能高效编辑PDF文档

在线PDF处理工具全攻略&#xff1a;零基础也能高效编辑PDF文档 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱&#xff0c;可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档&#xff0c;探查文档结构&#xff0c;提取图片、转成图片等等 项目地址: https://gitco…

作者头像 李华