【问题标题】:Python: mmap module's offset argument ExceptionPython:mmap 模块的偏移量参数异常
【发布时间】:2016-01-05 10:26:02
【问题描述】:

我正在使用 32 位 Windows(和 python)上的 1.5 GB 文件并使用 mmap 模块。

如您所见,我使用参数offset=0x5E2030AA 来获取我感兴趣的数据的起点。由于 mmap.mmap 模块的偏移量必须是mmap.ALLOCATIONGRANULARITY 的倍数,所以我' m 使用以下函数获取最近的偏移量:

def getNearestOffset(offset):
    nearest = offset
    nearest -= (offset % mmap.ALLOCATIONGRANULARITY)
    return nearest

然后我通过从nearestOffset 中减去传递的属性offset=0x5E2030AA 来寻找剩余的偏移量。

def readRIFF(fileno, bufLength=1024**3, offset=0x5E2030AA):
    partialData = False
    previousRIFF = None
    while True:
        nearestOffset = getNearestOffset(offset)
        with contextlib.closing(mmap.mmap(fileno, bufLength, offset=nearestOffset, access=mmap.ACCESS_READ)) as mm:
            if not partialData:
                mm.seek(offset - nearestOffset)
                startOffset = mm.tell()
                riffID = mm.read(4)
                assert riffID == "RIFF"
                riffSize = toLittleEndianInt(mm.read(4))
                riffType = mm.read(4)
                riffData = mm.read(riffSize - 4)
                # Check for partialData
                if len(riffData) != riffSize - 4:
                    print "DEBUG: Current RIFF blobs trunkated."
                    partialData = True
                    previousRIFF = riffBlob.RiffBlob(riffID, riffSize, riffType, riffData, startOffset)
                    break

但是当我尝试实例化一个新的 mmap 对象时(在 readRIFF 函数中),我得到以下异常:

Traceback (most recent call last):
  File "testRead.py", line 57, in <module>
    readRIFF(f.fileno())
  File "testRead.py", line 28, in readRIFF
    with contextlib.closing(mmap.mmap(fileno, bufLength, offset=nearestOffset, access=mmap.ACCESS_READ)) as mm:
WindowsError: [Error 8] Not enough storage is available to process this command

我很困惑,为什么会出现这个异常? 有没有其他方法可以访问我想要的偏移量? 我是否必须修改长度参数,因为我尝试读取的内容超过了文件的大小?

【问题讨论】:

    标签: python-2.7 mmap


    【解决方案1】:

    好吧,看来我自己找到了答案。

    上下文管理器 contextlib.closure 实际上并没有从内存中删除创建的内存映射 (?),因此我的内存在每次新调用时都会慢慢填满。

    在从 blob 中提取相关数据后,我通过简单地使用 del(mm) 删除内存映射来解决此问题。

    【讨论】:

      猜你喜欢
      • 2014-06-11
      • 2022-11-11
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多