2012-06-26 64 views
19

我正在嘗試使用Python的ftplib讀取文件而無需編寫它們。大致相當於:是否可以在不使用Python編寫FTP文件的情況下閱讀FTP文件?

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

但使用FTP。

我想:

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

但這不起作用。文檔中的唯一示例涉及使用ftp.retrbinary('RETR README', open('README', 'wb').write)格式寫入文件。是否可以在不先寫入的情況下讀取ftp文件?

+0

術語問題:你的問題的答案是你的問題,因爲「下載」的意思是「從服務器傳輸」,而不是「保存到磁盤」。您提供的'urllib'示例_does_下載文件;它只是不保存到磁盤。 – senderle

+0

聽起來像。可以在不打開的情況下閱讀一本書嗎? FTP僅用於傳輸文件。所以ftp協議沒有涉及讀取,運行或打開文件的操作。 另一個stackoverlow主題對java提出了同樣的問題。 FTP將文件作爲比特流發送。所以可以在下載過程中讀取和處理文件。 http://stackoverflow.com/questions/7690320/how-to-read-files-from-ftp-without-download-them – Erik

+0

是的,我意識到我張貼它後表達了很差......我會編輯現在。 – aensm

回答

35

那麼,你有正確的答案在你面前:retrbinary方法接受作爲第二個參數的函數的引用,每當從ftp連接檢索文件內容時調用該函數。

下面是一個簡單的例子:

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

你應該實現writeFunc因此,它實際上追加讀取內部變量,這樣的事情,它採用了可調用對象的數據:

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

更新:我意識到在Python標準庫中有一個模塊用於這種類型的東西,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

太棒了,謝謝!我沒有意識到回調可能是用戶定義的函數 – aensm

+1

對於Python 3,retrbinary需要BytesIO,因爲它返回字節,而不是字符串。如果你想要StringIO,請嘗試ftp.retrlines() –

相關問題