r+模式下readlines()为何会影响write()的写入位置?
哈哈,这个问题我之前也踩过坑!核心是Python文件操作里的缓冲区和文件指针交互,还有r+模式下读写切换的未定义行为,咱们一步步拆解清楚:
1. r+模式的正常行为
r+是读写双开的模式,打开文件时指针默认停在文件开头。正常情况下,直接执行写入操作会从当前指针位置开始覆盖内容,写完后指针会跳到写入内容的末尾。比如你去掉fh.readlines()时,write('Line0\n')会覆盖原文件开头的对应长度内容,最后close()会自动把缓冲区内容刷到磁盘,就得到了你预期的Line0 Line2。
2. 为什么加了fh.readlines()就变成追加了?
问题出在写入后直接读取的未定义操作:
- 当你执行
fh.write('Line0\n')时,数据并没有立刻写入磁盘,而是暂存在Python的内存缓冲区里——这是操作系统和Python为了效率做的优化。 - 这时候你直接调用
fh.readlines(),Python需要读取文件内容,但因为你没有先做flush()(把缓冲区内容刷到磁盘)或者seek()(重新定位指针),它会直接去读磁盘上的原始文件(也就是Line1 Line2),读完后指针就跑到了文件末尾。 - 最后执行
fh.close()时,Python才会把缓冲区里的Line0\n写入磁盘,但此时指针已经在文件末尾了,所以这部分内容就被追加到了原文件后面,最终变成Line1 Line2 Line0。
3. 怎么避免这个坑?
如果你确实需要在写入后读取文件,一定要先做下面其中一步:
- 调用
fh.flush():强制把缓冲区内容刷到磁盘,确保写入生效; - 调用
fh.seek(0):把指针重新定位到开头(或者你需要读取的位置)。
比如修改后的代码:
fh = open('text.txt','r+') fh.write('Line0\n') fh.flush() # 先把写入内容刷到磁盘 fh.seek(0) # 指针移回开头 print(fh.readlines()) fh.close()
这样既能正常读取到写入后的内容,最终文件也会是你预期的Line0 Line2。
内容的提问来源于stack exchange,提问作者multigoodverse
相关产品推荐
相关产品推荐

