2012-06-26 9 views
19

Próbuję odczytać pliki za pomocą ftplib Pythona bez ich pisania. Coś mniej więcej równoważnego:Czy można odczytać pliki FTP bez pisania ich za pomocą Pythona?

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

ale za pomocą FTP.

Próbowałem:

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

ale to nie działa. Jedyne przykłady w dokumentach dotyczą zapisywania plików w formacie ftp.retrbinary('RETR README', open('README', 'wb').write). Czy można odczytać pliki ftp bez uprzedniego zapisu?

+0

terminologiczną zastrzeżenie: odpowiedź na pytanie, jak masz sformułowane nie jest, bo „pobranie” oznacza „przeniesienie z serwera”, a nie „zapisz na dysku”. Przykład "urllib", który dałeś _does_, pobierz plik; po prostu nie zapisuje go na dysku. – senderle

+0

Brzmi jak. Czy można przeczytać książkę bez jej otwierania? FTP jest przeznaczony do przesyłania plików. Tak więc protokół ftp nie podejmuje żadnych działań, które wymagają czytania, uruchamiania lub otwierania pliku. Kolejny temat stackoverlow stawia to samo pytanie dla java. FTP wysyła plik jako strumień bitów. Dzięki temu można odczytać i obsłużyć plik podczas pobierania. http://stackoverflow.com/questions/7690320/how-to-read-files-from-ftp-without-download-them – Erik

+0

Tak, zdałem sobie sprawę, że źle to sformułowałem po tym, jak to opublikowałem ... teraz. – aensm

Odpowiedz

35

Cóż, masz prawo odpowiedzieć przed tobą: Metoda retrbinary akceptuje jako drugi parametr referencję do funkcji, która jest wywoływana, gdy treść pliku jest pobierana z połączenia ftp.

Oto prosty przykład:

#!/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) 

Należy wdrożyć writeFunc tak, że rzeczywiście dopisuje odczytane dane do zmiennej wewnętrznej, coś jak ten, który używa wpłacone obiekt:

#!/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 

Aktualizacja: zdałem sobie sprawę, że istnieje moduł w bibliotece standardowej Pythona, który jest przeznaczony do tego rodzaju rzeczy, 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

Awesome, thanks! Nie wiedziałem, że wywołanie zwrotne może być użytkownik funkcję – aensm

+1

zdefiniowane dla Pythona 3 retrbinary wymaga BytesIO, ponieważ zwraca bajty, a nie ciąg. Jeśli chcesz StringIO, spróbuj ftp.retrlines() –

Powiązane problemy