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

问题描述 投票:0回答:1

我有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)文件“ /usr/lib/python3.5/gzip.py”,第274行,处于读取状态返回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())
python serialization gzip
1个回答
1
投票

我检查了您的示例文件,发现长​​度字段不是编码为L,而是编码为<L。我的猜测是,如果L的原始长度等于4个字节的标准值,则它们在32位平台上进行了序列化,而您在[L的原始长度为[ C0]是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': ['انجام',
   'کلیه',
   'خدمات',
   'ترویج',
   'آموزش',
   [...]
© www.soinside.com 2019 - 2024. All rights reserved.