r、r+、rb、rb+文件打开模式区别
这个问题在面试里其实挺常见的,尤其是碰到那些喜欢刨根问底的面试官,稍不留神就会被问到文件打开模式的区别。别看这几个模式r、r+、rb、rb+字母加号加b,看着都差不多,其实背后的逻辑还真不简单,而且踩坑的机会也不少⚠️。
我们先来点直白的总结(这部分你面试前最好烂熟于心):
r:只读模式,文件必须存在,读操作OK,写就别想了。r+:读写模式,文件必须存在,可以读可以写,但写是覆盖而不是追加。rb:二进制读模式,和r一样,只是数据以二进制方式读取。rb+:二进制读写模式,文件必须存在,读写都行,处理的是原始字节数据。
听起来都很正常对吧?但你要是以为“r+就比r多了写权限”这么简单,那你很可能就中招了……
比如有一次我在写一个小工具,初衷很简单,从一个配置文件里读取参数,然后更新某些字段,想都没想就用了r+打开文件,结果读取完一部分后直接写新值,结果把后面的内容整个打乱了。为啥?因为写操作不是“插入”,而是从当前位置开始“覆盖”原来的内容!😵💫
来看个具体例子:
with open("test.txt", "w") as f:
f.write("abcdefg")
with open("test.txt", "r+") as f:
print(f.read(3)) # 输出 abc
f.write("XYZ") # 写入时从第四个字符开始覆盖
运行完之后,你去看test.txt的内容,会变成:
abcXYZg
你看,原来的d, e, f被干掉了,只剩下g顽强地留了下来…
这里顺便提一句:r+是不会自动“清空”文件内容的,也不会帮你补齐写入后的尾巴,写完哪里算哪里,后面没覆盖到的内容会原封不动保留。你要是真的想替换文件内容,老实用w+或者写完后再truncate()吧。
再说rb和rb+,很多人觉得它俩只是多了个“b”,根本没区别。其实不是。Python的文件操作在文本模式(默认)下,会自动处理一些换行符,比如Windows系统中"\r\n"会自动转换为"\n",而在二进制模式下,这些操作一律不做,按字节原样处理。
举个例子你就明白了:
with open("test.txt", "w", newline="") as f:
f.write("line1\r\nline2\r\n")
with open("test.txt", "r") as f:
print(f.read()) # 输出 line1\nline2\n
with open("test.txt", "rb") as f:
print(f.read()) # 输出 b'line1\r\nline2\r\n'
这在处理图片、视频、音频文件,或者网络协议的时候就显得尤其重要了——你可不想Python自动给你“优化”数据格式。
我还见过更魔幻的场景,一个哥们用rb+写配置文件,结果上线后用Windows下的Notepad打开乱码一片。后来才发现他以为二进制可以“通吃一切”,没注意编辑器也要讲格式。
面试的时候,如果你能举出这些场景,不仅能说明你懂区别,还能反映你真写过实战代码,绝对加分✅。
这些模式虽然名字上只是几个字母组合,但实际用起来的坑真不少。写程序的时候不要觉得“反正能用就行”,文件模式不对,轻则读不到东西,重则数据直接覆盖,生产上翻车那可是要背锅的…
你遇到过类似的问题吗?或者你有没有用过w+结果文件内容全被清空了的“社死瞬间”?
最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek
也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。