0

我在 python 中看到了多个教程,使用了 python 文件 write()、tell()、seek() 函数以及 os.write()、lseek() 函数。

但我仍然不明白如何执行以下操作: 我所拥有的:在一个文件中,我知道 start_offset 和 end_offset 字节。我需要用一组不同的字节替换从 start_offset 到 end_offset 的字节。我该怎么做呢??

ftell() 返回 start_offset 并且类似地 regex + ftell() 返回结束偏移量 我有字节将覆盖文件中的原始字节。

但是 write() 只需要一个字符串来写入。另外我如何从 start_pos 覆盖到 end_pos?

感谢任何指示/建议

4

2 回答 2

3

.seek()在-ing 回到你的start_offset位置之后,你写下确切的字符数 == 字节。然后这些会覆盖之前存在的数据。

如果需要,您可以将其拆分为多个写入,甚至一次写入一个字符(字节)。

于 2013-05-13T17:57:58.707 回答
2

尽管你大声否认,你可以在这里使用mmap

如果您查看mmapdocs 中的构造函数,它需要参数offsetlength。在大多数平台上,两者都必须是该值或相似值的倍数PAGESIZE,但这并不太难。

所以:

try:
    PAGESIZE = mmap.PAGESIZE
except NameError:
    PAGESIZE = mmap.ALLOCATION_GRANULARITY

def overwrite(fileobj, start, end, newbytes):
    startoffset, startremainder = divmod(start, PAGESIZE)
    offset = startoffset * PAGESIZE
    endoffset, endremainder = divmod(end, PAGESIZE)
    length = (endoffset + 1) * PAGESIZE - offset
    map = mmap.mmap(fileobj.fileno(), offset=offset, length=length,
                    access=mmap.ACCESS_WRITE)
    map[startremainder:startremainder+end-start] = newbytes

这有一个很好的优势,如果len(newbytes) != end - start你会从 中得到一个很好的异常mmap,而不是覆盖比你预期的更多或更少的文件并留下损坏的东西。

但它可能更容易使用seek,就像 Martijn Pieters 的回答一样。这是与 相同的功能seek

def overwrite(fileobj, start, end, newbytes):
    if len(newbytes) != end - start:
        raise ValueError('overwrite cannot expand or contract a file')
    fileobj.seek(start)
    fileobj.write(newbytes)    

尽管如此,值得知道mmap可以做什么,这样您就不会在将来的有用案例中忽略它。

(此外,对于某些版本的 Python,在某些平台上,您可能拥有太大而无法seek放入的文件。例如,linux/proc/*/map是一个大小为 的稀疏文件1<<64,但在某些发行版上,Python 找不到fseeko,因此找不到比 . 更远的地方了1<<63。因此,了解其他方法(<code>os.lseekmmap等)可能会帮助您有一天解决问题。)

于 2013-05-13T18:02:48.553 回答