这似乎是io.TextIOWrapper
(在文本模式下open
返回的类)与io.BufferedRandom
(在+
模式下包装的类)如何交互的错误。 )。
如果您将测试用例更改为以二进制模式运行:
with open('file','rb+') as f:
print(f.tell())
print(f.readline().strip())
print(f.tell())
# f.seek(f.tell())
f.write(b'Hello')
print(f.tell())
无论是否包含多余的f.seek(f.tell())
,行为都是相同的。
该问题似乎是由于所涉及的多层缓冲引起的。您得到的是一个io.TextIOWrapper
包装了一个io.BufferedRandom
(这反过来又包装了一个io.FileIO
)。 TextIOWrapper
从io.BufferedRandom
读取块以分摊从字节到文本的解码成本,因此,当您调用readline
时,它实际上是在消耗并解码整个文件(它很小,适合一小块),将BufferedRandom
放在文件末尾(即使从逻辑上讲,它应该只位于文件中间),TextIOWrapper.tell
报告对应于该逻辑位置的位置。
当您转向write
时,TextIOWrapper
对数据进行编码并将其传递到BufferedRandom
,后者仍然认为自己位于文件的末尾;由于TextIOWrapper
不能更正此问题,因此数据将附加到最后。看似无操作的f.seek(f.tell())
将TextIOWrapper
与下标BufferedRandom
重新同步,以获得预期的行为。确实没有必要(我建议filing a bug确保write
转到逻辑tell
的位置,因为尽管Python 3 f.tell() gets out of sync with file pointer in binary append+read mode是表面上相似),但至少解决方法相对简单。
,
问题与缓冲的IO有关。
open()函数似乎打开了一个缓冲文件句柄。
因此,实际上,每当读取文件中的内容时,至少会读取整个缓冲区,该缓冲区似乎在我的计算机上约为8k(8192)字节。
这是为了优化性能。
因此readline将读取一个块,并返回第一行,并将其余的块保留在缓冲区中,以备将来读取。
f.tell()为您提供相对于readline()已返回的字节的位置。
这可以通过f.seek(f.tell())强制执行写指针
到您想要的地方。如果没有显式的seek语句,您将在缓冲区之后编写。
使用以下脚本来说明并查看输出:
您将看到,我尝试使用buffering
参数。
根据文档1的意思是行缓冲,但是我看不到任何行为上的变化。
with open("file","w") as f:
f.write(("*" * 79 +"\n") * 1000)
with open('file','r+',buffering=1) as f:
print(f.tell())
print(f.readline().strip())
print(f.tell())
# f.seek(f.tell())
f.write('Hello')
print(f.tell())
print("----------- file contents")
with open("file","r") as f:
pass
print(f.read())
print("----------- END")
因此,如果您在readline()之后进行写操作,则它将在读取的缓冲区之后写入新数据。
另一方面,
f.tell()返回您的位置,它告诉您已经返回了多少字节。
输出将是:
0
*******************************************************************************
80
8197
8202
----------- file contents
*******************************************************************************
*******************************************************************************
...
*******************************************************************************
********************************HelloHello*************************************
*******************************************************************************
*******************************************************************************
*******************************************************************************
*******************************************************************************
...
本文链接:https://www.f2er.com/3155504.html