2010-08-23 16 views
6

Mi piacerebbe scaricare, estrarre e scorrere su un file di testo in Python senza dover creare file temporanei.Scarica, estrai e leggi un file gzip in Python

in fondo, questo tubo, ma in pitone

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

Ecco il mio codice:

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 

Non voglio usare process.Popen() o qualcosa perché voglio questo script per essere indipendente dalla piattaforma

Il problema è che la libreria Gzip accetta solo nomi di file come argomenti e non come handle. Il motivo per "piping" è che il passaggio di download utilizza solo una CPU superiore al 5% e sarebbe più veloce eseguire l'estrazione e l'elaborazione contemporaneamente.


EDIT: Questo non funzionerà perché

"A causa del modo di compressione gzip opere, GzipFile ha la necessità di salvare la sua posizione e spostarsi in avanti e indietro lungo il compresso file Questo non funziona quando il "file" è uno stream di byte proveniente da un server remoto , tutto ciò che si può fare con esso è Eve byte uno alla volta, non spostare avanti e indietro attraverso il flusso di dati ". - dive into python

che è il motivo per cui ho l'errore

AttributeError: addinfourl instance has no attribute 'tell' 

Così come fa curl url | gunzip | whatever lavoro?

+1

Perché non è presente in file Python separati? 'python download.py | python extract.py | python filter.py'? –

+0

Perché eseguire script Python da comandi di sistema da script Python è complicato. Inoltre, ho detto che voglio che questo sia indipendente dalla piattaforma (nel senso che quelle persone che usano Windows non avranno problemi), e l'esecuzione dei comandi di sistema lo rende difficile. DOS supporta anche le piping? –

risposta

9

Solo gzip.GzipFile(fileobj=handle) e sarete sulla buona strada - in altre parole, non è proprio vero che "la libreria Gzip accetta solo nomi di file come argomenti e non handle", è sufficiente utilizzare l'argomento con nome fileobj=.

+0

Grazie! Non l'ho visto nel docu. –

+0

@ Austin, prego! –

+1

Ricordare che l'oggetto file deve supportare 'seek'. – Andrey