我有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())
我检查了您的示例文件,发现长度字段不是编码为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': ['انجام',
'کلیه',
'خدمات',
'ترویج',
'آموزش',
[...]