Подтвердить что ты не робот

Можно ли читать файлы FTP, не записывая их с помощью Python?

Я пытаюсь читать файлы с использованием Python ftplib, не записывая их. Что-то примерно эквивалентно:

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 без записи в первую очередь?

4b9b3361

Ответ 1

Ну, у вас есть ответ прямо перед вами: метод 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 io 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: StringIO был добавлен в io. Объединенный комментарий @TimRichardson.: