Zip и ftp строки на лету с Python

Я хочу заархивировать строку (может быть очень большой) и отправить ее через FTP. Пока я использую ftplib и ziplib, но они не очень хорошо ладят.

ftp = FTP(self.host)
ftp.login(user=self.username, passwd=self.password)
ftp.cwd(self.remote_path)

buf = io.BytesIO(str.encode("This string could be huge!!"))

zip = ZipFile.ZipFile(buf, mode='x')
# Either one of the two lines 
ftp.storbinary("STOR " + self.filename, buf) # Works perfectly!
ftp.storbinary("STOR " + self.filename, zip) # Doesnt Work

ftp.quit()

Строка, которая не работает, вызывает следующую ошибку.

KeyError: 'There is no item named 8192 in the archive'

Я безуспешно пытался заархивировать файл в bytesio.

Мне нужно сделать все это в памяти. Я не могу сначала записать zip-файл на сервер, а затем на ftp.

Кроме того, мне нужно сделать это через чистый FTP, без SFTP или SSH.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
711
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы неправильно понимаете проблему.

ftp.storbinary нужен объект bytes, а не объект ZipFile. Вам необходимо создать объект bytes со сжатыми данными из несжатых данных и передать его в ftp.storbinary. Кроме того, вы должны предоставить название для файла в архиве.

этот фрагмент создает такой объект из строки (автономный пример)

import zipfile,io

output_io = io.BytesIO()

zipfile_ob = zipfile.ZipFile(output_io,"w",zipfile.ZIP_DEFLATED)
zipfile_ob.writestr("your_data.txt",b"big string to be compressed"*20)
zipfile_ob.close()

теперь адаптировано к вашему контексту:

ftp = FTP(self.host)
ftp.login(user=self.username, passwd=self.password)
ftp.cwd(self.remote_path)

buf = str.encode("This string could be huge!!")
output_io = io.BytesIO()

zipfile_ob = zipfile.ZipFile(output_io,"w",zipfile.ZIP_DEFLATED)
zipfile_ob.writestr("your_data.txt",buf)
zipfile_ob.close()
output_io.seek(0)   # rewind the fake file
ftp.storbinary("STOR " + self.filename, output_io)

ftp.quit()

Часть seek необходима, иначе вы передаете файловый объект output_io, находясь в конце файла (вы только что записали в него, поэтому текущая позиция: конец потока). Использование seek(0) перематывает файловый объект, чтобы его можно было прочитать с самого начала.

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

Другие вопросы по теме