我想压缩一个字符串(可能很大)并通过 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
对象。
关于python - 使用 Python 即时压缩和 ftp 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51358672/