尽管你大声否认,你可以在这里使用mmap。在
如果您看一下^{} constructor in the docs,它接受offset和{}的参数。在大多数平台上,两者都必须是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相同的函数:
^{pr2}$
不过,值得知道mmap可以做什么,这样您就不会在将来的有用案例中忽略它。在
(另外,对于某些版本的Python,在某些平台上,可能会有太大而无法seek的文件。例如,linux /proc/*/map是一个大小为1<<64的稀疏文件,但是在某些发行版上,Python找不到fseeko,因此不能搜索到比1<<63更远的地方。因此,了解其他方法来做这件事-os.lseek,mmap等等-也许有一天能帮助你解决一个问题。)