2012-06-26 9 views
19

Tôi đang cố đọc các tệp bằng cách sử dụng ftplib của Python mà không cần viết chúng. Nội dung nào đó tương đương với:Có thể đọc các tệp FTP mà không cần viết chúng bằng Python không?

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

nhưng sử dụng FTP.

tôi đã cố gắng:

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

nhưng điều này không hoạt động. Các ví dụ duy nhất trong tài liệu liên quan đến việc viết tệp bằng định dạng ftp.retrbinary('RETR README', open('README', 'wb').write). Có thể đọc các tệp ftp mà không cần viết trước không?

+0

Một thuật ngữ phân biệt: câu trả lời cho câu hỏi của bạn như bạn đã diễn đạt nó là không, bởi vì "tải xuống" có nghĩa là "chuyển từ máy chủ", chứ không phải "lưu vào đĩa". Ví dụ 'urllib' bạn đã cho _does_ tải xuống tệp; nó chỉ không lưu nó vào đĩa. – senderle

+0

Âm thanh như thế nào. Có thể đọc một cuốn sách mà không cần mở nó không? FTP chỉ được thiết kế để truyền tệp. Vì vậy, giao thức ftp không có hành động nào liên quan đến việc đọc, chạy hoặc mở một tệp. Chủ đề xếp chồng khác cũng đặt ra cùng một câu hỏi cho java. FTP gửi tệp dưới dạng luồng bit. Vì vậy, có thể đọc và xử lý tệp trong khi tải xuống. http://stackoverflow.com/questions/7690320/how-to-read-files-from-ftp-without-download-them – Erik

+0

Vâng, tôi nhận ra rằng tôi đã nói sai rằng sau khi tôi đăng nó ... Tôi sẽ chỉnh sửa hiện nay. – aensm

Trả lời

35

Vâng, bạn có câu trả lời ngay trước mặt bạn: Phương thức retrbinary chấp nhận tham số thứ hai là tham chiếu đến hàm được gọi bất cứ khi nào nội dung tệp được truy xuất từ ​​kết nối ftp.

Dưới đây là một ví dụ đơn giản:

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

Bạn nên thực hiện writeFunc để nó thực sự gắn thêm các dữ liệu đọc cho một biến nội bộ, một cái gì đó như thế này, trong đó sử dụng một đối tượng có thể được gọi:

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

Cập nhật: Tôi nhận ra rằng có một mô-đun trong thư viện chuẩn Python có nghĩa là cho loại điều này, 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

Tuyệt vời, cảm ơn! Tôi đã không nhận ra gọi lại có thể là một hàm do người dùng định nghĩa – aensm

+1

Đối với Python 3, retrbinary yêu cầu BytesIO, bởi vì nó trả về byte, không phải chuỗi. Nếu bạn muốn StringIO, hãy thử ftp.retrlines() –