C语言 fopen() 文件打开模式:w / wb / w+ / wb+ / a / ab / a+ / ab+ 完整区别
核心两大概念先分清:
- 有无 b:
b = binary 二进制模式;不带b = 文本模式(Windows下会自动转换\n ↔ \r\n,Linux/macOS文本/二进制无区别)- w = write 新建覆盖;a = append 追加;+ = 增加读权限
一、逐个解析
1. w 文本写模式
FILE *fp = fopen("test.txt", "w");
- 功能:创建文件
- 文件存在:直接清空原有全部内容,从头开始写
- 文件不存在:新建文件
- 权限:只可写,不能读
- Windows:文本模式,自动换行转换
\n <=> \r\n - 不能移动文件指针读取原有内容
2. wb 二进制写模式
- 和
w逻辑一模一样,唯一差别:二进制模式,不自动转换换行符 - 常用于图片、视频、结构体、二进制数据,强烈推荐存二进制文件用 wb
3. w+ 文本读写
- 文件存在:清空内容;不存在:新建
- 可读 + 可写
⚠️重点陷阱:打开后文件指针在开头,文件已经清空!原先数据全部丢失
读写切换必须调用fseek()/rewind()移动指针
- 文本换行自动转换
4. wb+ 二进制读写(最常用二进制读写模式)
行为 = w+ + 二进制模式
✅ 文件存在:清空;不存在新建
✅ 同时支持读、写
✅ 无换行字符转换
适用场景:需要读写二进制文件(缓存、自定义二进制格式)
5. a 文本追加模式
fopen("log.txt","a");
- 文件存在:不清空内容,每次写操作强制跳到文件末尾追加
- 文件不存在:新建
- 只能写,不能读
- 关键特性:无论你怎么 fseek 修改指针,fwrite/fputs 写入时依然强制跳到末尾
6. ab 二进制追加模式
和 a 规则一致,二进制模式,不转换换行
适合持续追加二进制日志、数据
7. a+ 文本追加+可读;ab+ 二进制追加+可读
- 文件存在:不清空;不存在新建
✅ 支持读 + 写
⚠️致命特性:
读取时指针可以自由移动;但是【写入操作永远强制追加到文件尾部】
哪怕你fseek跳到文件中间,一执行写操作,立刻跑到末尾追加,不能覆盖中间数据!
二、核心对比总表
| 模式 | 文件存在 | 文件不存在 | 可读 | 可写 | 写入特性 | 换行转换 |
|---|---|---|---|---|---|---|
w | 清空文件 | 创建 | ❌ | ✅ | 从头覆盖 | 文本(转换) |
wb | 清空文件 | 创建 | ❌ | ✅ | 从头覆盖 | 二进制(不转换) |
w+ | 清空文件 | 创建 | ✅ | ✅ | 从头覆盖 | 文本 |
wb+ | 清空文件 | 创建 | ✅ | ✅ | 从头覆盖 | 二进制 |
a | 保留内容 | 创建 | ❌ | ✅ | 强制末尾追加 | 文本 |
ab | 保留内容 | 创建 | ❌ | ✅ | 强制末尾追加 | 二进制 |
a+ | 保留内容 | 创建 | ✅ | ✅ | 读可任意位置;写强制末尾 | 文本 |
ab+ | 保留内容 | 创建 | ✅ | ✅ | 读可任意位置;写强制末尾 | 二进制 |
三、高频易错点(重点记忆)
-
w/w+打开瞬间就清空文件!
不要想用w+修改已有文件,一打开原始数据直接销毁。修改已有二进制文件 → 使用
rb+(重点!rb+不会清空) -
a/a+无法覆盖文件中间内容
只能追加到尾巴,这是操作系统底层行为,无法通过fseek规避。 -
Windows 一定要区分文本/二进制
保存图片、压缩包、结构体数据 禁止不带b,否则二进制字节0x1A会被当成文件结束符,数据损坏。Linux 有无b效果一致,但跨平台代码统一加上b最佳实践。
四、场景选型建议
- 新建二进制文件、从头写入:
wb - 需要新建+同时读写二进制文件:
wb+ - 打开已有二进制文件,保留原有数据,支持读写、局部覆盖:
rb+ - 持续写日志、不断追加数据,不需要读取:
ab - 追加日志同时偶尔读取文件内容:
ab+
如果你需要,我可以给你一段极简测试代码,直观演示 wb+ 和 ab+、rb+ 的行为差异。

1834

被折叠的 条评论
为什么被折叠?



