2010-08-23 79 views
6

我想在Python中下载,提取和遍历文本文件,而无需创建临时文件。下载,解压并在Python中读取gzip文件

基本上,这条管道,但是在Python

curl ftp://ftp.theseed.org/genomes/SEED/SEED.fasta.gz | gunzip | processing step 

这里是我的代码:

def main(): 
    import urllib 
    import gzip 

    # Download SEED database 
    print 'Downloading SEED Database' 
    handle = urllib.urlopen('ftp://ftp.theseed.org/genomes/SEED/SEED.fasta.gz') 


    with open('SEED.fasta.gz', 'wb') as out: 
     while True: 
      data = handle.read(1024) 
      if len(data) == 0: break 
      out.write(data) 

    # Extract SEED database 
    handle = gzip.open('SEED.fasta.gz') 
    with open('SEED.fasta', 'w') as out: 
     for line in handle: 
      out.write(line) 

    # Filter SEED database 
    pass 

我不想使用process.Popen()或任何东西,因为我想这个脚本与平台无关。

问题是,Gzip库只接受文件名作为参数而不处理。 “管道”的原因是下载步骤只使用了大约5%的CPU,并且同时运行提取和处理会更快。


编辑: 这不会起作用,因为

“因为这样gzip压缩 作品,GzipFile中需要保存其 位置,并通过压缩向前向后移动并 文件 当“文件”是来自远程服务器的 字节流时,这不起作用;您只能使用 retri每次前进一个字节,不会通过数据流 来回移动 。“ - dive into python

这就是为什么我得到的错误

AttributeError: addinfourl instance has no attribute 'tell' 

那么,如何curl url | gunzip | whatever工作?

+1

为什么不在单独的Python文件中? 'python download.py | python extract.py | python filter.py'? – 2010-08-23 14:33:50

+0

因为从python脚本中执行系统命令执行python脚本很麻烦。另外,我说我希望这是平台独立的(意味着那些使用Windows的人不会有任何问题),并且执行系统命令会使得这很困难。 DOS甚至支持管道? – 2010-08-23 15:36:06

回答

9

只需gzip.GzipFile(fileobj=handle),你就会在你的路上 - 换句话说,“Gzip库只接受文件名作为参数而不处理”并不是真的,你只需要使用fileobj=命名参数。

+0

谢谢!在文件中没有看到。 – 2010-08-23 15:21:50

+0

@奥斯汀,不客气! – 2010-08-23 15:28:00

+1

请记住文件对象必须支持'seek'。 – Andrey 2015-02-05 17:54:43