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

时间:2011-05-06 21:10:50

标签: python insert mmap

我正在使用Python编写一个脚本,该脚本使用mmap()映射文件以进行处理。

这些任务要求我通过

更改文件的内容
  1. 更换数据
  2. 以偏移量
  3. 将数据添加到文件中
  4. 从文件中删除数据(不是将其删除)
  5. 只要旧数据和新数据具有相同的字节数,替换数据就会很有效:

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

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

      

    IndexError:mmap切片分配是   错误的大小

    这是有道理的。

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

2 个答案:

答案 0 :(得分:6)

由于缺乏替代方案,我继续编写了两个辅助函数 - 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

答案 1 :(得分:2)

如果没有明确地执行此操作,则无法移动文件的内容(无论是mmap还是简单)。对于mmap的文件,您必须使用mmap.move方法。