我有大量的gzip压缩文件。
我编写了一段代码将这些文件拆分成较小的文件。我可以指明
每个文件的行数。事情是我最近增加了每次分割的线数
到16,000,000,当我处理更大的文件时,分裂不会发生。有时一个较小的文件
成功生产,有时一个生产但重量只有40B或50B,这是
失败。我试着通过查看gzip
中提出的异常来捕获异常
码。所以我的代码看起来像这样:
def writeGzipFile(file_name, content):
import gzip
with gzip.open(file_name, 'wb') as f:
if not content == '':
try:
f.write(content)
except IOError as ioe:
print "I/O ERROR wb", ioe.message
except ValueError as ve:
print "VALUE ERROR wb: ", ve.message
except EOFError as eofe:
print "EOF ERROR wb: ", eofe.message
except:
print "UNEXPECTED ERROR wb"
事情是当内容太高,与行数有关时,我经常得到
“意外错误”消息。所以我不知道这里会抛出哪种错误。
我终于发现行数是问题所在,并且看起来python的gzip
无法一次在一个文件中写入这么多数据。将每个拆分的行数减少到4,000,000个。但是我想拆分内容并按顺序写入文件,以确保写入高数据内容。
所以我想知道如何使用gzip
在文件中一次性找出可以写入的最大字符数,而不会出现任何故障。
编辑1
所以我要注意所有剩余的例外情况(我不知道有可能只是抓住Exception
抱歉):
def writeGzipFile(file_name, content, file_permission=None):
import gzip, traceback
with gzip.open(file_name, 'wb') as f:
if not content == '':
try:
f.write(content)
except IOError as ioe:
print "I/O ERROR wb", ioe.message
except ValueError as ve:
print "VALUE ERROR wb: ", ve.message
except EOFError as eofe:
print "EOF ERROR wb: ", eofe.message
except Exception, err:
print "EXCEPTION:", err.message
print "TRACEBACK_1:", traceback.print_exc(file=sys.stdout)
except:
print "UNEXPECTED ERROR wb"
错误大小约为int
。我从没想过有一天我会超过int大小:
EXCEPTION: size does not fit in an int
TRACEBACK_1:Traceback (most recent call last):
File "/home/anadin/dev/illumina-project-restructor_mass-splitting/illumina-project-restructor/tools/file_utils/file_compression.py", line 131, in writeGzipFile
f.write(content)
File "/usr/local/cluster/python2.7/lib/python2.7/gzip.py", line 230, in write
self.crc = zlib.crc32(data, self.crc) & 0xffffffffL
OverflowError: size does not fit in an int
None
好吧因此int的最大大小是2,147,483,647,根据我的日志,我的数据块大约是3,854,674,090。这个块是我应用__len__()
函数的字符串。
正如我计划的那样,正如Antti Haapala建议的那样,我一次只能阅读较小的块,以便按顺序将它们写入较小的文件。
答案 0 :(得分:5)
无论如何,我怀疑原因是某种内存不足的错误。我不清楚你为什么不把这些数据写得不那么频繁;这里使用chunks
方法from this answer:
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in xrange(0, len(l), n):
yield l[i:i+n]
...
with gzip.open(file_name, 'wb') as f:
for chunk in chunks(content, 65536):
f.write(chunk)
也就是说,你就像吃大象一样,一次咬一口。