0x9*_*x90 5 python mmap insert
我正在使用Python编写一个脚本,该脚本使用mmap()映射文件以进行处理.
这些任务要求我改变文件的内容
只要旧数据和新数据具有相同的字节数,替换数据就会很有效:
VDATA = mmap.mmap(f.fileno(),0)
start = 10
end = 20
VDATA[start:end] = "0123456789"
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试删除数据(用""替换范围)或插入数据(替换范围超过范围的范围)时,我收到错误消息:
IndexError:mmap切片分配大小错误
这是有道理的.
现在的问题是,如何插入和删除mmap的文件中的数据?通过阅读文档,我似乎可以使用一系列低级操作来回移动文件的整个内容,但如果有更简单的解决方案,我宁愿避免这种情况.
在缺少替代方案的情况下,我继续编写了两个辅助函数 - deleteFromMmap()和insertIntoMmap() - 来处理低级文件操作并简化开发.
关闭和重新打开mmap而不是使用resize()是对unix派生的python中的错误导致resize()失败.(http://mail.python.org/pipermail/python-bugs-list/2003-May/017446.html)
这些功能包含在一个完整的示例中.全局的使用归因于主项目的格式,但您可以轻松地对其进行调整以符合您的编码标准.
import mmap
# f contains "0000111122223333444455556666777788889999"
f = open("data","r+")
VDATA = mmap.mmap(f.fileno(),0)
def deleteFromMmap(start,end):
global VDATA
length = end - start
size = len(VDATA)
newsize = size - length
VDATA.move(start,end,size-end)
VDATA.flush()
VDATA.close()
f.truncate(newsize)
VDATA = mmap.mmap(f.fileno(),0)
def insertIntoMmap(offset,data):
global VDATA
length = len(data)
size = len(VDATA)
newsize = size + length
VDATA.flush()
VDATA.close()
f.seek(size)
f.write("A"*length)
f.flush()
VDATA = mmap.mmap(f.fileno(),0)
VDATA.move(offset+length,offset,size-offset)
VDATA.seek(offset)
VDATA.write(data)
VDATA.flush()
deleteFromMmap(4,8)
# -> 000022223333444455556666777788889999
insertIntoMmap(4,"AAAA")
# -> 0000AAAA22223333444455556666777788889999
Run Code Online (Sandbox Code Playgroud)