文件不写入当前文件位置

时间:2018-01-23 10:22:22

标签: python file io

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

1 个答案:

答案 0 :(得分:3)

这是由open返回缓冲的文件对象引起的。

当你正在阅读时,它会因为缓冲而读取幕后的所有文件(因为从磁盘读取char是无效的)。

f.tell()与您所阅读的内容一致,但在内部编写时,文件指针位于其他位置,这就是您必须通过强制seek来解决此问题的原因。

这只是“为什么?”,但恕我直言,这是一个错误(或限制),因为write应该/可以使用用户已知的位置而不是基础无缓冲文件的内部系统位置。

这在只读或只写流上不是问题,但在这个有趣的情况下这是一个问题。

现在你知道了:read之后的writewrite之后的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}}语句)