处理压缩文件下载,无需保留压缩数据(支持gzip和bzip2格式)

3
我想下载一个压缩文件(gzip或bzip2格式),解压并分析其内容(它是一个类似CSV的文件,包含大量数据,我要对某些列进行求和、平均值等计算),同时在下载过程中进行(以便我可以在下载完成前显示部分结果)。该文件非常大(4GB),解压后的流甚至更大,因此我不想将整个压缩文件保存在磁盘或内存中。我认为可以将Python的gzip或bz2实现与urllib2结合使用。
data_stream = csv.reader(
                  gzip.GzipFile(
                      fileobj=urllib2.urlopen('http://…/somefile.gz')),
                  delimiter='\t')

...但似乎urlopen的文件对于GzipFile来说不够像文件。在尝试从这样的流中读取后,我会得到一个回溯:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/gzip.py", line 450, in readline
    c = self.read(readsize)
  File "/usr/lib/python2.7/gzip.py", line 256, in read
    self._read(readsize)
  File "/usr/lib/python2.7/gzip.py", line 283, in _read
    pos = self.fileobj.tell()   # Save current position
AttributeError: addinfourl instance has no attribute 'tell'

BZ2模块更糟糕——它根本不允许传递文件对象。

经过寻找答案,我发现这个问题。答案的解决方法基本上是将整个压缩文件存储在内存中,而这对我来说是不可行的。

我该怎么办?


查看这个答案 - John
1个回答

3

使用Python中的zlibzlib.decompressobj会创建一个对象,可以逐行提供gzip压缩的数据,并使用对象上的decompress方法输出可用的未压缩数据。您需要将wbits设置为31以解码gzip格式。15将解码zlib格式。


是的,但是我需要一个包装对象来让它看起来像csv.reader的可迭代对象,对吧?有没有什么东西可以做到这一点? - liori
那是简单的部分。zlib已经为您完成了繁重的工作。 - Mark Adler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接