反序列化小型 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': ['انجام',
'کلیه',
'خدمات',
'ترویج',
'آموزش',
[...]
我有 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': ['انجام',
'کلیه',
'خدمات',
'ترویج',
'آموزش',
[...]