news 2026/2/22 23:22:34

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

作者头像

张小明

前端开发工程师

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

一、项目背景详细介绍

在 C++ 实际工程开发中,**二进制文件(Binary File)**的使用频率非常高,甚至在很多场景下远高于文本文件。

常见的二进制文件应用场景包括但不限于:

  • 音频文件(WAV / MP3 / PCM)

  • 图像文件(BMP / PNG / JPEG 原始数据)

  • 视频流数据

  • 网络协议数据包

  • 序列化后的对象数据

  • 缓存文件、索引文件

  • 游戏存档文件

  • 科学计算中的大规模数值数据

与文本文件相比,二进制文件具有以下显著特点:

  • 不具备可读性

  • 数据按字节精确存储

  • 不存在字符编码问题

  • 读写效率高

  • 结构完全由程序定义

因此,正确、严谨地读取二进制文件,是 C++ 工程能力中的一项“硬基础”

本项目将从最基础的概念开始,系统讲解:

如何使用 C++ 标准库安全、正确、高效地读取二进制文件

并给出一个可直接用于工程的教学级完整示例


二、项目需求详细介绍

2.1 功能性需求

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

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

  2. 从二进制文件中读取数据

  3. 支持读取:

    • 固定大小数据

    • 结构体数据

    • 整个文件到内存

  4. 正确处理文件大小与读取边界

  5. 输出读取结果用于验证


2.2 非功能性需求

为了满足教学与工程实践要求:

  • 仅使用 C++ 标准库

  • 不依赖任何第三方库

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

  • 可移植(Windows / Linux / macOS)

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


2.3 二进制文件特点说明

与文本文件不同,二进制文件:

  • 不能使用std::getline

  • 必须使用read接口

  • 必须明确读取字节数

  • 不自动处理换行符


三、相关技术详细介绍

3.1 C++ 二进制文件打开方式

使用std::ifstream并指定std::ios::binary

std::ifstream ifs("data.bin", std::ios::binary);

⚠️非常重要:

  • 不指定std::ios::binary,在 Windows 下可能导致数据被错误转换


3.2 二进制读取核心接口

ifs.read(char* buffer, std::streamsize size);

说明:

  • buffer:数据存放地址

  • size:要读取的字节数

  • 不关心数据内容,只按字节读取


3.3 文件大小获取方法

常用步骤:

  1. 移动到文件末尾

  2. 使用tellg()获取大小

  3. 再移动回文件开头


3.4 二进制与结构体

在工程中,二进制文件经常直接存储:

  • 基本类型

  • 数组

  • 结构体(POD 类型)

但必须注意:

  • 内存布局

  • 对齐方式

  • 字节序问题(大端 / 小端)


四、实现思路详细介绍

本示例采用最通用、最安全的方式

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

  2. 获取文件大小

  3. 分配足够的内存缓冲区

  4. 一次性读取全部内容

  5. 对读取的数据进行解析或输出

同时演示:

  • 读取基本类型

  • 读取结构体

  • 读取整个文件


五、完整实现代码

/******************************************************** * 文件名:read_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 文件路径 * @param buffer 输出缓冲区 * @return true 读取成功 * @return false 读取失败 */ bool readWholeBinaryFile( const std::string& fileName, std::vector<char>& buffer) { std::ifstream ifs(fileName, std::ios::binary); if (!ifs.is_open()) { return false; } // 移动到文件末尾以获取大小 ifs.seekg(0, std::ios::end); std::streamsize fileSize = ifs.tellg(); ifs.seekg(0, std::ios::beg); if (fileSize <= 0) { return false; } // 分配缓冲区 buffer.resize(static_cast<size_t>(fileSize)); // 一次性读取整个文件 ifs.read(buffer.data(), fileSize); ifs.close(); return true; } /** * @brief 从二进制文件中读取一个结构体 * @param fileName 文件路径 * @param data 输出结构体 * @return true 成功 * @return false 失败 */ bool readStructFromBinary( const std::string& fileName, DataBlock& data) { std::ifstream ifs(fileName, std::ios::binary); if (!ifs.is_open()) { return false; } // 直接按字节读取结构体大小 ifs.read(reinterpret_cast<char*>(&data), sizeof(DataBlock)); ifs.close(); return true; } int main() { // ================= 示例 1:读取整个二进制文件 ================= std::vector<char> fileBuffer; if (readWholeBinaryFile("data.bin", fileBuffer)) { std::cout << "成功读取整个二进制文件,大小:" << fileBuffer.size() << " 字节" << std::endl; } else { std::cout << "读取整个二进制文件失败" << std::endl; } // ================= 示例 2:读取结构体 ================= DataBlock data{}; if (readStructFromBinary("struct.bin", data)) { std::cout << "读取结构体成功:" << std::endl; std::cout << "id = " << data.id << std::endl; std::cout << "value = " << data.value << std::endl; std::cout << "flag = " << data.flag << std::endl; } else { std::cout << "读取结构体失败" << std::endl; } return 0; }

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

6.1readWholeBinaryFile

  • 以二进制模式打开文件

  • 获取文件总大小

  • 分配内存缓冲区

  • 一次性读取所有字节

  • 适合小到中等规模二进制文件


6.2readStructFromBinary

  • 直接按结构体大小读取二进制数据

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

  • 要求结构体是POD 类型


6.3main函数

  • 演示两种典型二进制读取方式

  • 验证读取结果

  • 为后续数据解析提供基础


七、项目详细总结

通过本项目,你系统掌握了:

  • C++ 二进制文件打开方式

  • read接口的正确使用

  • 文件大小获取技巧

  • 二进制与结构体映射关系

  • 工程中常见的二进制读取模式

这是:

  • 网络编程

  • 音视频处理

  • 游戏开发

  • 系统底层开发

必不可少的基础能力。


八、项目常见问题及解答

Q1:为什么必须使用std::ios::binary

在 Windows 下,文本模式会自动转换\r\n,导致数据损坏。


Q2:能直接读取std::string吗?

不推荐。
二进制文件应使用定长数据结构或明确长度


Q3:结构体跨平台安全吗?

不安全。
需注意:

  • 对齐

  • 字节序

  • 编译器差异


Q4:如何读取超大文件?

应使用分块读取(chunk read),避免一次性加载。


九、扩展方向与性能优化

9.1 分块读取大文件(流式处理)

9.2 字节序(Endian)转换工具

9.3 二进制协议解析器设计

9.4 二进制 + 内存映射(mmap)

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

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

如何拥有专属AI虚拟伙伴?Open-LLM-VTuber零代码部署指南

如何拥有专属AI虚拟伙伴&#xff1f;Open-LLM-VTuber零代码部署指南 【免费下载链接】Open-LLM-VTuber Talk to LLM by voice with Live2D that runs offline on multiple platforms. An attempt to build AI VTuber neuro-sama. 项目地址: https://gitcode.com/gh_mirrors/o…

作者头像 李华
网站建设 2026/2/22 5:00:27

C++:获取文件编码格式(附带源码)

一、项目背景详细介绍 在实际工程开发中&#xff0c;**文件编码格式&#xff08;Character Encoding&#xff09;**是一个极其容易被忽视、却又极其容易引发问题的基础点。 典型“编码问题”场景包括&#xff1a; 文本文件在不同系统下显示乱码 CSV / TXT 文件用 Excel 打开…

作者头像 李华
网站建设 2026/2/17 7:16:35

C++:写CSV文件(附带源码)

一、项目背景详细介绍 在实际工程与数据处理领域中&#xff0c;CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff09;文件是一种极其常见、生命力极强的数据交换格式。 CSV 文件被广泛应用于以下场景&#xff1a; 数据分析与数据挖掘&#xff08;Excel …

作者头像 李华
网站建设 2026/2/17 17:34:49

4步激活旧Mac潜能:OpenCore Legacy Patcher技术解析与实战指南

4步激活旧Mac潜能&#xff1a;OpenCore Legacy Patcher技术解析与实战指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当苹果停止对老旧Mac设备的系统支持时&#xff…

作者头像 李华
网站建设 2026/2/19 0:20:01

YOLO26如何提升FPS?imgsz/batch联合优化案例

YOLO26如何提升FPS&#xff1f;imgsz/batch联合优化案例 YOLO26作为Ultralytics最新发布的轻量级高精度目标检测模型&#xff0c;在保持mAP竞争力的同时&#xff0c;对实时性提出了更高要求。但很多用户反馈&#xff1a;明明硬件配置不低&#xff0c;推理速度却卡在30FPS上不去…

作者头像 李华
网站建设 2026/2/22 3:02:30

Selenium模拟滚动加载无限下拉页面

在爬虫开发或自动化测试中&#xff0c;我们经常会遇到 “无限下拉” 的页面&#xff08;比如微博信息流、电商商品列表、知乎回答流&#xff09;—— 这类页面不会一次性加载所有内容&#xff0c;只有当用户滚动到页面底部时&#xff0c;才会通过 AJAX 请求加载新数据。如果直接…

作者头像 李华