在mmap'ed文件中删除/插入数据

发布于 2021-01-29 15:12:52

我正在处理Python中的脚本,该脚本映射文件以使用mmap()处理。

这些任务要求我通过以下方式更改文件的内容

  1. 替换数据
  2. 将数据以一定的偏移量添加到文件中
  3. 从文件中删除数据(不删除数据)

只要旧数据和新数据具有相同的字节数,替换数据就可以很好地工作:

VDATA = mmap.mmap(f.fileno(),0)
start = 10
end = 20
VDATA[start:end] = "0123456789"

但是,当我尝试删除数据(用“”替换范围)或插入数据(用比该范围长的内容替换范围)时,收到错误消息:

IndexError:mmap切片分配大小错误

这很有道理。

现在的问题是,如何从mmap文件插入和删除数据?通过阅读文档,似乎我可以使用一系列低级操作来回移动文件的全部内容,但是如果有更简单的解决方案,我宁愿避免这种情况。

关注者
0
被浏览
166
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    在没有其他选择的情况下,我继续编写了两个辅助函数-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
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看