Загрузка файлов 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.

Кто-нибудь может сообщить, что происходит неправильно. Я прочитал, что ftp.storbinary используется для загрузки файлов с использованием FTP.

Ответ 1

Если вы пытаетесь сохранить недвоичный файл (например, текстовый файл), попробуйте установить его в режим чтения вместо режима записи.

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

для двоичного файла (что-либо, что не может быть открыто в текстовом редакторе), откройте ваш файл в режиме чтения двоичного файла

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

Кроме того, если вы планируете использовать ftp lib, вам, вероятно, стоит пройти учебник, я бы порекомендовал эту статью от effbot.

Ответ 2

Объедините оба предложения. Окончательный ответ

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

Ответ 3

попробуйте сделать файл объектом, поэтому вы можете закрыть его в конце операции.

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

и в конце передачи

 myfile.close()

это может не решить проблему, но это может помочь.

Ответ 4

ftplib поддерживает использование контекстных менеджеров, поэтому вы можете сделать его еще проще

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

Таким образом, вы устойчивы как к файлам, так и к файлам ftp без необходимости вставлять блоки try/исключением /finally. И хорошо, это питон.

PS: поскольку он использует f-strings, используется только python> = 3.6, но его легко изменить, чтобы использовать старый синтаксис .format().