我想下载一个压缩文件(在 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 模块更糟糕——它根本不允许传递文件对象。
在寻找一些答案后,我发现了这个问题。答案基本上是将整个压缩文件存储在内存中,这对我来说是不可行的。
我能做些什么?