web-dev-qa-db-ja.com

FTPアップロードファイルPython

WindowsサーバーからUNIXサーバーにファイルをアップロードしようとしています(基本的にFTPを実行しようとしています)。以下のコードを使用しました

#!/usr/bin/python
import ftplib
import os
filename = "MyFile.py"
ftp = ftplib.FTP("xx.xx.xx.xx")
ftp.login("UID", "PSW")
ftp.cwd("/Unix/Folder/where/I/want/to/put/file")
os.chdir(r"\\windows\folder\which\has\file")
ftp.storbinary('RETR %s' % filename, open(filename, 'w').write)

次のエラーが表示されます。

Traceback (most recent call last):
  File "Windows\folder\which\has\file\MyFile.py", line 11, in <module>
    ftp.storbinary('RETR %s' % filename, open(filename, 'w').write)
  File "windows\folder\Python\lib\ftplib.py", line 466, in storbinary
    buf = fp.read(blocksize)
AttributeError: 'builtin_function_or_method' object has no attribute 'read'

また、MyFile.pyのすべてのコンテンツが削除されました。

誰もが間違っていることをアドバイスできますか?.

13
misguided

非バイナリファイル(テキストファイルなど)を保存しようとしている場合は、書き込みモードではなく読み取りモードに設定してください。

ftp.storlines("STOR " + filename, open(filename, 'r'))

バイナリファイル(テキストエディタで開くことができないもの)の場合、ファイルを読み取りバイナリモードで開きます。

ftp.storbinary("STOR " + filename, open(filename, 'rb'))

また、ftp libの使用を計画している場合は、おそらくチュートリアルを行う必要があります。これは、effbotの article をお勧めします。

16
John

両方の提案を組み合わせました。最終的な回答

#!/usr/bin/python
import ftplib
import os
filename = "MyFile.py"
ftp = ftplib.FTP("xx.xx.xx.xx")
ftp.login("UID", "PSW")
ftp.cwd("/Unix/Folder/where/I/want/to/put/file")
os.chdir(r"\\windows\folder\which\has\file")
myfile = open(filename, 'r')
ftp.storlines('STOR ' + filename, myfile)
myfile.close()
8
misguided

ファイルをオブジェクトにしてみてください。そうすれば、操作の最後にファイルを閉じることができます。

myfile = open(filename, 'w')
ftp.storbinary('RETR %s' % filename, myfile.write)

そして、転送の終わりに

 myfile.close()

これは問題を解決しないかもしれませんが、役立つかもしれません。

3
mbdavis

ftplibコンテキストマネージャの使用をサポート ですので、それ自体をよりシンプルにすることができます

    with ftplib.FTP('ftp_address', 'user', 'pwd') as ftp, open(file_path, 'rb') as file:
        ftp.storbinary(f'STOR {file_path.name}', file)
        ...

これにより、try/except/finallyブロックを挿入することなく、ファイルとftpの両方の問題に対して堅牢になります。そしてまあ、それはPythonicです。

PS:f-stringsを使用するのはpython> = 3.6のみですが、古い.format()構文を使用するように簡単に変更できます

0
gbonetti