Я пытаюсь создать скрипт, который будет загружать 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 файлом".
Кто знает, почему это происходит? Я проверил следующее:
РЕДАКТИРОВАТЬ
Я читал о байтах IO и т.п., Но без каких-либо успехов в его реализации.
вероятно, из-за этой плохой практики однострочный:
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
блоком (конечно, выполнить чтение файла операции за пределами этого блока).