C++ 二进制文件读写操作

发布时间:2026/9/10 10:41:49

C++ 二进制文件读写操作 在 C 中处理二进制文件如图像、音频、序列化数据等与处理文本文件有本质区别。二进制读写要求数据在内存中的布局与文件中完全一致不进行任何字符编码转换或格式化。以下是关于std::ifstream::read和std::ofstream::write的详解涵盖核心用法、关键规则及常见陷阱。1. 核心前提以二进制模式打开文件这是最容易忽略的一步。如果使用默认的文本模式打开文件某些操作系统如 Windows会在遇到特定字节序列时进行转换例如将\n转换为 \r\n导致二进制数据损坏。‌必须显式指定ios::binary标志‌#include fstream #include iostream // 写二进制文件 std::ofstream outFile(data.bin, std::ios::binary); if (!outFile.is_open()) { std::cerr 无法打开文件用于写入 std::endl; return; } // 读二进制文件 std::ifstream inFile(data.bin, std::ios::binary); if (!inFile.is_open()) { std::cerr 无法打开文件用于读取 std::endl; return; }2. 函数原型与参数解析写入函数ostream::writeostream write(const char* s, std::streamsize n);‌s(缓冲区指针)‌指向要写入的数据起始地址。‌注意‌参数类型强制为const char*因此任何类型的指针都需要强转为char*。‌n(字节数)‌要写入的字节总数。通常使用sizeof(变量)或数组长度 * sizeof(元素类型)计算。读取函数istream::readistream read(char* s, std::streamsize n);‌s(缓冲区指针)‌指向存放读取数据的内存地址。同样需要强转为char*。‌n(字节数)‌期望读取的字节数。3. 实战示例场景一读写基本数据类型直接读写int,float,struct等 PODPlain Old Data类型。struct Player { int id; float health; char name; }; void binaryIOExample() { Player p1 {101, 95.5f, Hero}; // --- 写入 --- std::ofstream out(player.dat, std::ios::binary); if (out) { // 写法(char*)变量, sizeof(变量) out.write(reinterpret_castconst char*(p1), sizeof(Player)); out.close(); } // --- 读取 --- Player p2; std::ifstream in(player.dat, std::ios::binary); if (in) { // 写法(char*)变量, sizeof(变量) in.read(reinterpret_castchar*(p2), sizeof(Player)); // 检查是否成功读取了预期大小的数据 if (in.gcount() sizeof(Player)) { std::cout ID: p2.id , Health: p2.health std::endl; } else { std::cerr 读取数据不完整 std::endl; } in.close(); } }场景二读写数组/缓冲区如图像像素对于大型数据块一次性读写效率远高于循环逐字节读写。void arrayIOExample() { const int SIZE 1024; unsigned char buffer[SIZE]; // 初始化数据 for(int i0; iSIZE; i) buffer[i] static_castunsigned char(i % 256); // --- 写入整个数组 --- std::ofstream out(raw_data.bin, std::ios::binary); if (out) { // 数组名本身就是指针无需 但需强转 out.write(reinterpret_castconst char*(buffer), SIZE); out.close(); } // --- 读取整个数组 --- unsigned char readBuffer[SIZE]; std::ifstream in(raw_data.bin, std::ios::binary); if (in) { in.read(reinterpret_castchar*(readBuffer), SIZE); // 验证读取状态 if (in.fail()) { std::cerr 读取过程中发生错误 std::endl; } in.close(); } }4. 关键规则与最佳实践‌指针强转是必须的‌read和write的参数类型固定为char*或const char*。无论你的数据是int*、double*还是struct*都必须使用reinterpret_castchar*进行转换。推荐使用 C 风格的reinterpret_cast而非 C 风格的(char*)以提高代码可读性和安全性意识。‌严禁使用和运算符‌和是格式化 I/O 运算符它们会将数字转换为 ASCII 字符串例如整数123会被写成字符1,2,3并忽略空白符。这完全破坏了二进制数据的结构。‌二进制读写只能使用read()和write()。‌‌数据类型选择unsigned charvschar‌在处理原始字节流如图像像素、网络包时建议使用unsigned char。因为char在某些编译器下默认是有符号的-128 到 127可能导致位运算或数值比较出现意外行为。unsigned char保证范围是 0-255完美对应一个字节Byte。‌检查读取状态‌read不会自动在末尾添加\0也不会保证一定能读满请求的字节数例如文件剩余不足。使用in.gcount()获取实际读取的字节数。使用in.eof()检查是否到达文件尾。使用in.fail()或in.bad()检查是否发生严重错误。‌结构体对齐问题Padding‌如果直接读写struct需注意编译器可能会在成员之间插入填充字节Padding以满足内存对齐要求。风险不同编译器、不同平台32位 vs 64位的对齐方式可能不同导致生成的二进制文件不兼容。解决使用#pragma pack(1)强制紧凑排列非标准但广泛支持。或者手动序列化每个成员而不是直接读写整个结构体。‌对象包含指针时不能直接读写‌如果结构体或类中包含指针如std::string,std::vector,char*‌绝对不能‌直接使用write(obj, sizeof(obj))。原因sizeof只计算指针本身的大小4或8字节而不是指针指向的数据。写入的只是内存地址读取后该地址无效会导致崩溃。解决必须手动序列化指针指向的内容先写长度再写数据。5. 常见错误总结错误做法正确做法原因ifstream in(file.bin);ifstream in(file.bin, ios::binary);缺少二进制标志Windows下换行符会被转换。in variable;in.read((char*)variable, sizeof(variable));是文本格式化输入会破坏二进制结构。write(ptr, size)其中 ptr 未强转6写操作代码实战图解帮助初学者加强理解#includeiostream using namespace std; #includefstream class Person { public: char m_Name[64]; //姓名 int m_Age; //年龄 }; void test01(){ //1、包含头文件 //2.创建流对象 ofstream ofs(person.txt,ios::out | ios::binary); //3、打开文件 //ofs.open(person.txt,ios::out | ios::binary) ; //4、写文件 Person p { 张三,18 }; ofs.write((const char *)p, sizeof(Person)); //5、关闭文件 ofs.close(); } //二进制文件写文件 int main() { test01(); system(pause); return 0; }我们打开文件的路径发现多了一个person.txt文件文件打开就是长下面这个样子哦
延伸阅读

更多相关文章

2026/9/6 0:36:33

如何快速掌握Web安全扫描:Arachni框架的完整入门指南

如何快速掌握Web安全扫描:Arachni框架的完整入门指南 【免费下载链接】arachni Web Application Security Scanner Framework 项目地址: https://gitcode.com/gh_mirrors/ar/arachni Arachni是一款功能全面、模块化的高性能Ruby框架,专为帮助渗透…

2026/9/8 18:35:17

老视频画质太差?用Video2X让模糊画面瞬间变清晰

老视频画质太差?用Video2X让模糊画面瞬间变清晰 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/video2x …

2026/9/10 10:37:18

CANN/ge编译选项设置

aclSetCompileopt 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、TensorFl…

2026/9/10 10:37:18

如何把老 SWF 跑起来:Ruffle Flash 模拟器快速上手指南

如何把老 SWF 跑起来:Ruffle Flash 模拟器快速上手指南 【免费下载链接】ruffle A Flash Player emulator written in Rust 项目地址: https://gitcode.com/GitHub_Trending/ru/ruffle Ruffle 是一个用 Rust 编写的 Flash Player 模拟器(当前版本…

2026/9/10 10:37:18

没有AB实验怎么做因果推断?PSM倾向得分匹配实战指南

做AB实验做得久了,你会慢慢意识到一个扎心的事实:不是所有场景都能给你一个干净的随机分组。用户在产品里已经走了一圈,你没法把他们“打回原形”重新抽签。这时候还硬套AB实验的框架,出来的结论不是偏的就是假的,甚至…

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码