使用 Python 动态压缩和 ftp 字符串

Zip and ftp a string on the fly with 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。

我认为你在错误地看待问题。

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 对象可能更好。