[C++高频精进] 文件IO:二进制与文本处理

核心要点速览

  • 本质区别:文本基于字符编码(含格式 / 编码转换),二进制基于原始字节流(无任何转换);
  • 差异:可读性(文本可读 / 二进制不可读)、效率(二进制 > 文本)、适用场景(文本→日志 / 配置,二进制→图片 / 结构体);
  • 操作:文本用>>/<</getline(),二进制用read()/write()+ios::binary
  • 补充:本质区别对比、结构体二进制读写禁忌、场景选择依据、跨平台兼容原理。

一、本质区别:从存储到操作的差异

文本处理和二进制处理的所有差异,根源在于数据存储形式和读写时是否进行转换

对比维度文本处理(Text Mode)二进制处理(Binary Mode)
存储形式以字符编码(ASCII/UTF-8 等)存储,数据需转换为字符编码(如int 123→字符串 “123”)以原始二进制存储,直接复刻内存字节布局(如int 123→0x7B 0x00 0x00 0x00)
读写转换自动处理换行符(Windows:\n\r\n;Linux:不转换),支持编码互转无任何转换,字节数据原样读写(\n=0x0A,\r=0x0D)
人类可读性可直接用记事本打开阅读(日志、ini 配置等)打开为乱码,需程序解析(图片、结构体数据等)
处理效率需编码 / 解码 + 格式转换,效率较低直接操作内存字节,无额外开销,效率极高
数据完整性适合无结构 / 弱结构化数据,解析依赖分隔符(空格、换行)适合结构化数据,完整性依赖字节对齐、类型长度规范
跨平台兼容性换行符转换可能导致兼容问题,编码统一(UTF-8)后适配较好需处理字节对齐、字节序、类型长度差异,否则解析错位

二、原理:两种模式的设计逻辑

1. 文本处理:为 “人类可读” 设计

  • 目标:适配人类阅读 / 编辑习惯,支持跨平台文本共享;
  • 特性:字符编码映射(数据→字符)、自动换行符适配、按字符 / 单词 / 行读写,贴合人类操作逻辑。

2. 二进制处理:为 “高效存储 + 机器解析” 设计

  • 目标:最大化效率与数据准确性,适配机器间传输 / 存储;
  • 特性:字节级复刻内存布局、无任何额外转换、支持结构化数据批量读写,解析速度极快。

三、操作实践:函数与示例

1. 文本处理:操作与注意事项

函数
  • 写入:<<(格式化输出)、put()(单个字符)、endl(换行 + 刷新);
  • 读取:>>(按空白分割)、getline()(读整行)、get()(读单个字符)。
示例:读写文本日志
// 写入
ofstream log("log.txt", ios::app);
if (!log.is_open()) return -1;
log << "[" << __TIME__ << "] 操作成功" << endl;
log.close();

// 读取
ifstream ifs("log.txt");
string line;
while (getline(ifs, line)) cout << line << endl;
ifs.close();
注意事项
  • >>getline()混用:>>残留换行符,需用ifs.ignore(numeric_limits<streamsize>::max(), '\n')清除;
  • 编码一致性:中文需统一编码(如 UTF-8),避免乱码。

2. 二进制处理:操作与注意事项

函数
  • 写入:write(const char* buf, streamsize n)(强转char*);
  • 读取:read(char* buf, streamsize n)
  • 模式要求:必须显式指定ios::binary
示例:读写结构体
#pragma pack(1) // 关闭字节对齐
struct User { int32_t id; char name[20]; double score; };
#pragma pack()

// 写入
ofstream ofs("users.bin", ios::out | ios::binary);
User u = {101, "Alice", 95.5};
ofs.write(reinterpret_cast<const char*>(&u), sizeof(u));
ofs.close();

// 读取
ifstream ifs("users.bin", ios::in | ios::binary);
User u2;
ifs.read(reinterpret_cast<char*>(&u2), sizeof(u2));
if (ifs.good()) cout << u2.id << " " << u2.name << " " << u2.score << endl;
ifs.close();
注意事项
  • 字节对齐:#pragma pack(1)强制紧凑存储,避免编译器填充空白字节;
  • 禁用动态类型:string/vector含指针,需用固定长度数组;
  • 字节序:跨平台用htonl()/ntohl()转换为网络字节序(大端)。

四、场景决策:如何选择处理模式?

1. 优先选文本模式

  • 需人类查看 / 编辑:日志、配置文件(.ini)、CSV 表格;
  • 数据无复杂结构,需跨程序共享(如 Excel 读取 CSV)。

2. 优先选二进制模式

  • 结构化数据:结构体、数组;
  • 非文本文件:图片(.jpg)、音频(.mp3)、视频(.mp4);
  • 追求极致效率:大文件传输、高频读写(如数据库存储);
  • 加密 / 隐私数据:避免编码转换导致密文失真。

3. 禁忌场景

  • 文本模式不读写结构体 / 非文本文件(易失真);
  • 二进制模式不存储需编辑内容(如配置文件);
  • 二进制不读写含动态内存的类型(如string)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值