Zip-файл не распознается при загрузке через FTP

1

Я пытаюсь создать скрипт, который будет загружать ZIP файл и извлекать его.

Я использую Python 2.7 на Windows Server 2016.

Я создал сценарий загрузки, который выглядит так:

ftp = FTP()
ftp.connect("***")
ftp.login("***","***")
ftp.cwd(ftppath)
ftp.retrbinary("RETR " + filename ,open(tempfile, 'wb').write)
ftp.quit()

И скрипт извлечения zip:

zip_ref = zipfile.ZipFile(tempfile, 'r')
zip_ref.extractall(localpath)
zip_ref.close()

Они работают независимо. Значение: Если я запустил сценарий извлечения в моем тестовом ZIP файле, он извлечет файл. Также, если я запустил FTP-скрипт с моего сервера, он загрузит файл.

Тем не мение! Если я запускаю скрипты вместе, это означает, что я загружаю файл с моего FTP-сервера, а затем извлекаю его, он вернет ошибку: "файл не является Zip файлом".

Кто знает, почему это происходит? Я проверил следующее:

  • Исправить папку
  • Загрузка zip файла, извлечение его и его повторное сжатие (тогда скрипт извлечет его)

РЕДАКТИРОВАТЬ

Я читал о байтах IO и т.п., Но без каких-либо успехов в его реализации.

Теги:
python-2.7
zipfile
zip

1 ответ

1
Лучший ответ

вероятно, из-за этой плохой практики однострочный:

ftp.retrbinary("RETR " + filename ,open(tempfile, 'wb').write)

open(tempfile, 'wb').write не дает никаких гарантий относительно того, когда файл закрыт. Вы не храните дескриптор, open любом месте, поэтому вы не можете решить, когда close файл (и обеспечить полную запись на диск).

Таким образом, последняя часть файла может быть просто не записана на диск, но при попытке открыть его в режиме чтения. И chaining download + unzip может вызвать ошибку (когда два отдельных исполнения оставляют время для скрытия и закрытия файла)

Лучше использовать контекстный менеджер следующим образом:

with open(tempfile, 'wb') as f:
    ftp.retrbinary("RETR " + filename ,f.write)

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

  • 0
    Ах, это имеет много смысла! И это сработало. Большое спасибо за быстрый и очень точный ответ!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню