Python中'r+'模式下read后write文件指针位置异常原因探究
Python r+模式下read与write的文件指针行为解析
问题背景
我正在学习Python文件处理,在使用r+模式时,搞不懂连续调用read和write方法时的文件指针行为。
测试文件aTestTextFile3.txt初始内容:
012345678901234567890123456789
疑惑场景1:read后直接write,内容被追加到末尾
>>> f = open('aTestTextFile3.txt', 'r+') # 文件指针位于起始位置 >>> f.read() '012345678901234567890123456789' # 文件指针移至末尾 >>> f.seek(0); f.write('MONTUEWED') 0 9 # 文件指针最终停在位置9 >>> f.seek(0); f.read() 0 'MONTUEWED901234567890123456789' # 文件指针回到末尾 >>> f.tell() 30 # 确认指针处于文件末尾 >>> f.seek(0); f.read(9) 0 'MONTUEWED' # 文件指针移动到位置9 >>> f.tell() 9 # 确认指针位置为9 >>> f.write('THURS') 5 >>> f.tell() 35 # 结果:THURS被写入文件末尾 >>> f.seek(0); f.read() 0 'MONTUEWED901234567890123456789THURS'
疑问:明明write前tell()显示指针在位置9,为什么THURS会被写到文件末尾?是之前的read调用导致的吗?
疑惑场景2:read后调用seek(0,1)再write,内容写入指针位置
>>> f.seek(0); f.read(9) 0 'MONTUEWED' # 文件指针移动到位置9 >>> f.tell() 9 # 确认指针位置为9 >>> f.seek(0, 1) 9 # 无偏移移动指针,位置仍为9 >>> f.write('THURS') 5 >>> f.tell() 14 # 结果:THURS被写入指针位置(9)之后 >>> f.seek(0); f.read() 0 'MONTUEWEDTHURS4567890123456789THURS'
疑问:是不是write前如果有过read调用,必须先调用seek移动指针到当前位置,才能让写入操作生效在指针处?
正常场景:write后直接read无异常
>>> f.seek(0); f.write('Greetings to thee!') 0 18 # 文件指针最终停在位置18 >>> f.read() '890123456789THURS' >>> f.seek(0); f.read() 0 'Greetings to thee!890123456789THURS'
这部分操作中,write后直接调用read是完全正常的。
核心原因解析
这是Python文本模式下r+模式的缓冲机制导致的:
- 当你执行
read操作后直接调用write,Python会自动将文件指针移动到文件末尾再执行写入——这是为了避免读写缓冲区冲突,是文本模式下的隐形规则。 - 而调用
seek(0, 1)时,这个操作会强制刷新缓冲区并确认当前指针位置,打破了上述隐形规则,此时write会严格按照当前指针位置执行写入(覆盖后续内容)。
总结关键规则:
- 文本模式下,
read后直接write:自动追加到文件末尾 read后调用seek(哪怕是无偏移的seek(0,1)):同步缓冲区,写入操作遵循当前指针位置write后直接read:无异常,因为写入后缓冲区会自动同步,指针位置更新正确
内容的提问来源于stack exchange,提问作者Sommerwind845
相关产品推荐
相关产品推荐

