Python就地写入任意位置的文件



我正试图在python中编辑一个文本文件。它非常大(因此无法将其加载到内存中)。我打算用我在里面找到的逐字节字符串替换它。

with f as open("filename.txt", "r+b"):
    if f.read(8) == "01234567":
        f.seek(-8, 1)
        f.write("87654321")

然而,当我尝试时,write()操作会添加到文件的末尾:

>>> n.read()
'sdf'
>>> n.read(1)
''
>>> n.seek(0,0)
>>> n.read(1)
's'
>>> n.read(1)
'd'
>>> n.write("sdf")
>>> n.read(1)
''
>>> n.seek(0,0)
>>> n.read()
'sdfsdf'
`

我希望结果是sdsdf

当读写模式流从读模式切换到写模式时,原始的ANSI/ISO C标准需要进行查找操作,反之亦然。这种限制持续存在,例如,n1570包括以下文本:

当以更新模式打开文件时('+'是上述模式参数值列表中的第二个或第三个字符),可以对相关流执行输入和输出。但是,在没有对fflush函数或文件定位函数(fseekfsetposrewind)的干预调用的情况下,输出后不应直接跟着输入,并且在没有对文件定位函数的干预调用情况下,输入后不应直接输出,除非输入操作遇到文件结尾。在某些实现中,以更新模式打开(或创建)文本文件可能会打开(或生成)二进制流。

无论出于何种原因,这个限制已经导入到Python中,1,即使Python包装器可以自动处理它。

值得一提的是,最初ANSI C限制的原因是在许多基于Unix的系统上发现的低预算实现:它们为每个流保留一个"当前字节计数"one_answers"当前指针"。如果宏化的getcputc操作必须调用底层实现,则当前字节计数为0,底层实现可以检查流是否在更新模式下打开,并根据需要进行切换。但是,一旦您成功地获得了一个字符,计数器就会保存可以继续从底层流中读取的字符数;一旦您成功地编写了一个字符,计数器就会保存允许添加字符的缓冲区位置的数量。

这意味着,如果您成功地执行了一个getc,它填充了一个内部缓冲区,但后面跟着一个putc,那么putc中的"写入"字符将简单地覆盖缓冲的数据。如果您有一个成功的putc,但随后又有一个实现不佳的getc,那么您将看到缓冲区中的未设置值。

这个问题很难解决(只需提供单独的输入和输出计数器,其中一个始终为零,并具有为模式切换实现缓冲区重新填充检查的功能)。


1需要引用:-)

您可以检查以下代码的差异:

>>> f = open("file.txt", "r+b")
>>> f.seek(2)
>>> f.write("sdf")
>>> f.seek(0)
>>> f.read()
'sdsdf'

>>> f = open("file.txt", "r+b")
>>> f.read(1)
's'
>>> f.read(1)
'd'
>>> f.write("sdf")
>>> f.seek(0)
>>> f.read()
'sdfsdf'

.write的指针最初位于文件的末尾。只有.seek()会改变它的位置,而不是.read()。所以在写入字节之前必须调用.seek(。以下代码运行良好:

>>> f = open("file.txt", "r+b")
>>> f.read(1)
's'
>>> f.read(1)
'd'
>>> f.seek(2)
>>> f.write("sdf")
>>> f.seek(0)
>>> f.read()
'sdsdf'

相关内容

  • 没有找到相关文章

最新更新