反序列化小型 gzip 文件时出现内存错误

Memory error in deserializing small gzip file

我有 30 个 gzip 文件需要反序列化。我使用以下代码作为反序列化代码:

def deserialize(f):
    retval = {}
    while True:
        content = f.read(struct.calcsize('L'))
        if not content: break
        k_len = struct.unpack('L', content)[0]
        k_bstr = f.read(k_len)
        k = k_bstr.decode('utf-8')
        v_len = struct.unpack('L', f.read(struct.calcsize('L')))[0]
        v_bytes = os.io.BytesIO(f.read(v_len))
        v = numpy.load(v_bytes, allow_pickle=True)
        retval[k] = v.item()
    return retval


for i in range(0,26):

    with gzip.open('Files/company'+str(i)+'.zip','rb') as f:
        curdic1 = deserialize(f)
    n = 0
    for key in curdic1:
        n = n + 1
        company = curdic1[key]
        if (n % 10000 == 1):
            print(i, key)

但是当它在反序列化过程中出现以下异常时:

k_bstr = f.read(k_len) File "/usr/lib/python3.5/gzip.py", line 274, in read return self._buffer.read(size) MemoryError

此外,每个文件的大小小于 4 MB!。那么这段代码有什么问题?

已编辑: sample file]

已编辑 这是序列化方法,如果可以帮助澄清......:

def serialize(f, content):
    for k,v in content.items():
        # write length of key, followed by key as string
        k_bstr = k.encode('utf-8')
        f.write(struct.pack('L', len(k_bstr)))
        f.write(k_bstr)
        # write length of value, followed by value in numpy.save format
        memfile = io.BytesIO()
        numpy.save(memfile, v)
        f.write(struct.pack('L', memfile.tell()))
        f.write(memfile.getvalue())

我检查了您的示例文件,发现长​​度字段未编码为 L,而是编码为 <L。我的猜测是它们是在 32 位平台上序列化的 L 的本机长度等于 4 个字节的标准值,而你是 运行 64 位平台上的反序列化函数L 的原始长度为 8 个字节。所以函数应该是:

import struct, io
import numpy as np

def deserialize(f):
    retval = {}
    while True:
        content = f.read(struct.calcsize('<L'))
        if not content: break
        k_len = struct.unpack('<L', content)[0]
        k_bstr = f.read(k_len)
        k = k_bstr.decode('utf-8')
        v_len = struct.unpack('<L', f.read(struct.calcsize('<L')))[0]
        v_bytes = io.BytesIO(f.read(v_len))
        v = np.load(v_bytes, allow_pickle=True)
        retval[k] = v.item()
    return retval

示例文件的部分反序列化输出:

{'12000001': {'NID': '',
  'companyid': '12000001',
  'newspaperdate': '۱۳۸۵/۶/۲۰',
  'indikatornumber': '۱۸۹۶۲',
  'newsdate': None,
  'newstitle': 'آگهی تاسیس شرکت فنی مهندسی آریا\u200cپژوه گرمسار (سهامی خاص)',
  'persons': [],
  'subjects': ['انجام',
   'کلیه',
   'خدمات',
   'ترویج',
   'آموزش',
   [...]