у меня есть 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 (размер) MemoryError

Кроме того, размер каждого файла составляет менее 4 МБ !. так в чем проблема с этим кодом?

Отредактировано: образец файла ]

< Сильный > Edited это метод сериализации, если может помочь уточнить ...:

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())
0
MaSepehr 20 Дек 2019 в 19:40

1 ответ

Лучший ответ

Я проверил ваш пример файла и обнаружил, что поля длины были закодированы не как 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': ['انجام',
   'کلیه',
   'خدمات',
   'ترویج',
   'آموزش',
   [...]
1
Seb 21 Дек 2019 в 14:47