2012-06-26 18 views
19

Sto provando a leggere i file usando il ftplib di Python senza scriverli. Qualcosa o meno equivalente a:È possibile leggere i file FTP senza scriverli usando Python?

def get_page(url): 
    try: 
     return urllib.urlopen(url).read() 
    except: 
     return "" 

ma tramite FTP.

ho provato:

def get_page(path): 
    try: 
     ftp = FTP('ftp.site.com', 'anonymous', 'passwd') 
     return ftp.retrbinary('RETR '+path, open('page').read()) 
    except: 
     return '' 

, ma questo non funziona. Gli unici esempi nei documenti riguardano la scrittura di file utilizzando il formato ftp.retrbinary('RETR README', open('README', 'wb').write). È possibile leggere i file ftp senza scrivere prima?

+0

Un cavillo terminologico: la risposta alla domanda come è stata formulata è no, perché "download" significa "trasferimento dal server", non "salvataggio su disco". L'esempio 'urllib' che hai dato _does_ scarica il file; semplicemente non lo salva su disco. – senderle

+0

Sembra. È possibile leggere un libro senza aprirlo? FTP è progettato per trasferire file. Quindi il protocollo ftp non ha azioni che implichino la lettura, l'esecuzione o l'apertura di un file. Un altro argomento stackoverlow pone la stessa domanda per java. FTP invia il file come un flusso di bit. Quindi potrebbe essere possibile leggere e gestire il file durante il download. http://stackoverflow.com/questions/7690320/how-to-read-files-from-ftp-without-download-them – Erik

+0

Sì, mi sono reso conto di averlo scritto male dopo averlo postato ... Modificherò adesso. – aensm

risposta

35

Bene, avete la risposta proprio davanti a voi: il metodo retrbinary accetta come secondo parametro un riferimento a una funzione che viene chiamata ogni volta che il contenuto del file viene recuperato dalla connessione ftp.

Ecco un semplice esempio:

#!/usr/bin/env python 
from ftplib import FTP 

def writeFunc(s): 
    print "Read: " + s 

ftp = FTP('ftp.kernel.org') 
ftp.login() 
ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', writeFunc) 

Si dovrebbe implementare writeFunc in modo che aggiunge in realtà i dati letti ad una variabile interna, qualcosa di simile, che utilizza un oggetto invocabile:

#!/usr/bin/env python 
from ftplib import FTP 

class Reader: 
    def __init__(self): 
    self.data = "" 
    def __call__(self,s): 
    self.data += s 

ftp = FTP('ftp.kernel.org') 
ftp.login() 
r = Reader() 
ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', r) 

print r.data 

Aggiornamento: Mi sono reso conto che esiste un modulo nella libreria standard Python che è pensato per questo genere di cose, StringIO:

#!/usr/bin/env python 
from ftplib import FTP 
from StringIO import StringIO 

ftp = FTP('ftp.kernel.org') 
ftp.login() 
r = StringIO() 
ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', r.write) 

print r.getvalue() 
+2

Fantastico, grazie! Non mi ero reso conto che il callback poteva essere una funzione definita dall'utente – aensm

+1

Per Python 3, retrbinary richiede BytesIO, perché restituisce i byte, non la stringa. Se vuoi StringIO, prova ftp.retrlines() –

Problemi correlati