with open('test.txt', 'w+') as f:
f.write('foo')
f.seek(0)
f.read(1)
print f.tell() # 1
f.write('bar')
我希望结果为fbar
,但会返回foobar
。显然,文件不会写在当前文件位置。
with open('test.txt', 'w+') as f:
f.write('foo')
f.seek(0)
f.read(1)
m = f.tell() # 1
f.seek(m)
f.write('bar')
它按预期工作。
为什么当前文件位置已在seek
时,我又需要1
?
答案 0 :(得分:3)
这是由open
返回缓冲的文件对象引起的。
当你正在阅读时,它会因为缓冲而读取幕后的所有文件(因为从磁盘读取char是无效的)。
f.tell()
与您所阅读的内容一致,但在内部编写时,文件指针位于其他位置,这就是您必须通过强制seek
来解决此问题的原因。
这只是“为什么?”,但恕我直言,这是一个错误(或限制),因为write
应该/可以使用用户已知的位置而不是基础无缓冲文件的内部系统位置。
这在只读或只写流上不是问题,但在这个有趣的情况下这是一个问题。
现在你知道了:read
之后的write
或write
之后的read
,即使您认为seek
,也要使用os.open
文件是正确的。
作为替代方案,您可以使用ftell
来确保不涉及缓冲(对系统调用进行一些调整,因为import os
f = os.open('test.txt',os.O_RDWR|os.O_TRUNC)
os.write(f,b'foo') # b prefix needed, stream is binary
os.lseek(f, 0, os.SEEK_SET)
os.read(f,1)
# print(os.lseek(f, 0, os.SEEK_CUR)) # to seek/get current
os.write(f,b'bar')
os.close(f)
不存在,您必须从当前到得到当前的pos):
fbar
在这种情况下你可以lseek
完全正确(即使禁用{{1}}语句)