web-dev-qa-db-ja.com

Pythonを使用して書き込むことなくFTPファイルを読み取ることはできますか?

私はそれらを書かずに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ファイルを読み取ることはできますか?

28
aensm

さて、あなたの目の前に答えがあります:retrbinaryメソッドは、ftp接続からファイルコンテンツが取得されるたびに呼び出される関数への参照を2番目のパラメーターとして受け入れます。

以下に簡単な例を示します。

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

pdate: 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()

pdate 2: StringIOがioに組み込まれました。 @TimRichardsonのコメントを組み込みました。

47
daniel kullmann