C语言fopen函数r+与rb+文件访问模式的差异疑问
r+与rb+文件打开模式的实质差异 两种模式的区别来自C标准定义的文本流、二进制流的行为分歧,是否会引发读取错误,和程序运行的操作系统直接相关:
- 在Linux、macOS等类Unix系统上,C标准库对文本流和二进制流的实现没有区别,不会对读写的字节做任何额外转换。这种环境下用
r+和rb+打开文件的效果完全一致,读出来的内容和磁盘存储的原始字节完全匹配,这也是你当前读取结果正确的最常见原因。 - 在Windows系统上,两种模式的行为存在明确差异:
r+属于文本读写模式,读取过程中标准库会自动做两类特殊处理:一是把磁盘上存储的Windows原生行尾\r\n双字节替换为单个\n字节返回;二是读到0x1A(Ctrl+Z字符)时会直接判定为文件结束,停止后续读取。写入时也会做反向的换行符转换。rb+属于二进制读写模式,不会触发任何上述转换逻辑,会逐字节原样返回磁盘上的所有数据,也不会特殊识别0x1A为文件结束标记。
你当前没读到错误内容,属于“碰巧没触发问题”的情况:除了前面说的类Unix环境无差异的情况,如果你在Windows上运行、但写入的二进制文件里刚好没有
\r\n字节序列、也不存在0x1A字节,也不会触发文本模式的转换逻辑,读出来的内容暂时是对的,但代码存在跨平台兼容隐患。
如果写入时明确使用了"ab"二进制追加模式,说明文件存储的是原始二进制数据,读取时必须显式使用"rb+"模式打开。否则代码放到Windows环境运行、且文件内容刚好触发文本模式转换规则时,必然会出现读取结果错误,常见问题包括读取到的字节长度和实际文件大小不符、部分字节值被篡改、遇到0x1A提前截断读取等。
内容的提问来源于stack exchange,提问作者Crazy circuit
相关产品推荐
相关产品推荐

