
本文介绍一下二进制输出文件的规则及其作用。目录1 概述2 二进制输出3 示例4 说明1 概述流最初是为文本处理设计的因此文件输出默认采用文本模式。在文本模式下写入时单个换行符 \n 会自动扩展为 Windows 系统的回车 换行双字符 \r\n。这种自动转换会破坏二进制数据示例如下// binary_output_files.cpp// compile with: /EHsc#includefstreamusingnamespacestd;intiarray[2]{99,10};intmain(){ofstreamos(test.dat);os.write((char*)iarray,sizeof(iarray));}开发者预期输出字节序列{99,0,10,0}但文本模式下实际写入{99,0,13,10,0}多插入了回车符 \r后续读取二进制数据的程序会解析出错。2 二进制输出如果需要纯粹的二进制输出、字节原样写入不做任何字符转换构造 ofstream 时传入ios_base::binary打开模式标志// binary_output_files2.cpp// 编译参数/EHsc#includefstreamusingnamespacestd;intiarray[2]{99,10};intmain(){ofstreamofs(test.dat,ios_base::binary);// 精确写入8个字节无任何字符转译ofs.write((char*)iarray[0],sizeof(int)*2);}3 示例下述示例分别通过文本模式和二进制模式写入然后二进制模式读取查看区别文本模式读取查看区别// binary_output_files.cpp// 编译参数/EHsc#includefstream#includeiostreamusingnamespacestd;intiarray[2]{99,10};intmain(){//文本模式写入无ios::binary{ofstreamos(test.dat);os.write((char*)iarray,sizeof(iarray));os.close();//二进制读取ifstreamis(test.dat,ios::binary);charbuf[16]{0};is.read(buf,sizeof(buf));is.close();//逐字节打印十六进制观察多出0x0D(13)cout文件内字节(十六进制)endl;for(inti0;isizeof(iarray)2;i){printf(%02X ,(unsignedchar)buf[i]);}coutendl;//文本模式读取intreadArr[2]{0};ifstreamtextIn(test.dat);textIn.read((char*)readArr,sizeof(readArr));textIn.close();cout预期数组[99, 10]endl;cout文本模式读回[readArr[0], readArr[1]]endl;}//二进制模式写入ios::binary{ofstreamos(test2.dat,ios::binary);os.write((char*)iarray,sizeof(iarray));os.close();//二进制读取ifstreamis(test2.dat,ios::binary);charbuf[16]{0};is.read(buf,sizeof(buf));is.close();//逐字节打印十六进制观察多出0x0D(13)cout文件内字节(十六进制)endl;for(inti0;isizeof(iarray)2;i){printf(%02X ,(unsignedchar)buf[i]);}coutendl;//文本模式读取intreadArr[2]{0};ifstreamtextIn(test2.dat);textIn.read((char*)readArr,sizeof(readArr));textIn.close();cout预期数组[99, 10]endl;cout文本模式读回[readArr[0], readArr[1]]endl;}return0;}运行结果很明显二进制读取的时候是有问题的但是文本模式写入二进制模式读取本身逻辑上就不通畅所以什么方式写入什么方式读取不就好了。4 说明文本模式转换规则仅 Windows 平台生效写入内存中的 \n 0x0A自动变成 \r\n 0x0D 0x0A存入文件读取文件里连续的 \r\n 自动还原为单个 \nLinux / macOS 无此转换文本、二进制模式行为一致二进制模式核心作用添加 ios_base::binary 后所有字节原样落地不会插入、替换任何换行相关字符适合结构体、数组、图片、程序等二进制数据持久化。风险场景使用 write()序列化数字、结构体时必须加 binary否则数值中出现 0x0A 就会多出 0x0D字节长度错乱读取数据完全失真。