尽管你大声否认,你可以在这里使用mmap。
如果您查看mmapdocs 中的构造函数,它需要参数offset和length。在大多数平台上,两者都必须是该值或相似值的倍数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等)可能会帮助您有一天解决问题。)