gzip 无法在文件中写入大量数据

gzip fails at writing high amount of data in file

我有很大的 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"

问题是当内容太高时,与行数有关,我经常得到 "UNEXPECTED ERROR" 消息。所以我不知道这里会抛出哪种错误。

我终于发现是行数的问题,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 所建议的那样,我将一次读取较小的块,以便将它们依次写入较小的文件。

无论如何,我怀疑原因是某种内存不足错误。我很不清楚你为什么不一次写少量的数据;这里使用 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)

也就是像吃大象一样,一口咬一口。