.zip文件在通过gmail api发送并通过zlib压缩后被损坏 [英] .zip file gets corrupted when sent with gmail api and compressed with zlib

查看:108
本文介绍了.zip文件在通过gmail api发送并通过zlib压缩后被损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python 3.7,并使用python的zipfilezlib压缩.csv文件.

I am using Python 3.7 and compressing a .csv file using python's zipfile and zlib.

import zipfile

filename = "report.csv"

zip_filename = f"{filename[:-4]}.zip"
with zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED) as zip:
    zip.write(filename)

然后将zip文件附加到电子邮件中,我有一些逻辑来确定其MIME类型(我已经检查了它是否正确确定它为application/zip):

The zip file is then attached to an email, I have some logic to determine its MIME type (I have checked that it correctly determines that it's application/zip):

def _make_attachment_part(self, filename: str) -> MIMEBase:
    content_type, encoding = mimetypes.guess_type(filename)
    if content_type is None or encoding is not None:
        content_type = "application/octet-stream"

    main_type, sub_type = content_type.split("/", 1)
    msg = MIMEBase(main_type, sub_type)
    with open(filename, "rb") as f:
        msg.set_payload(f.read())

    base_filename = os.path.basename(filename)
    msg.add_header("Content-Disposition", "attachment", filename=base_filename)

    return msg

然后,为MIMEMultipart类型的message设置主题,收件人,抄送,附件等.然后,我使用base64进行编码并将其发送出去.

Then, the subject, recipients, cc, attachments etc. are set for the message which is of the MIMEMultipart type. Then, I use base64 for encoding and send it through.

raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode()

我收到的附件名称正确且具有预期的大小,但是,当我尝试使用unzip file.zip时,出现以下错误:

I receive my attachment named correctly and of the expected size, however, when I try to use unzip file.zip, I get the following error:

error [file.zip]:  missing 5 bytes in zipfile

有人知道我在做什么错吗?事实上,电子邮件是从Ubuntu计算机发送的,而我正在尝试在MacOS上打开接收到的文件.

Does anyone have any idea what I'm doing wrong? As a matter of fact, the email is sent from Ubuntu machine, whereas I'm trying to open the received file on MacOS.

推荐答案

rfc1341 :

7BIT的编码类型要求主体已经采用了7位邮件就绪表示形式.这是默认值,即如果不存在Content-Transfer-Encoding标头字段,则假定为"Content-Transfer-Encoding:7BIT".

An encoding type of 7BIT requires that the body is already in a seven-bit mail- ready representation. This is the default value -- that is, "Content-Transfer-Encoding: 7BIT" is assumed if the Content-Transfer-Encoding header field is not present.

对于您而言,在_make_attachment_part函数中,您要将有效负载设置为MIMEBase对象,但未指定Content-Transfer-Encoding.

In your case, in the _make_attachment_part function, you are setting the payload to your MIMEBase object, but you are not specifying the Content-Transfer-Encoding.

我建议您将有效载荷编码为Base64.您可以按照以下步骤进行操作:

I suggest that you encode your payload as Base64. You can do it as follows:

  1. 导入encoders模块

from email import encoders

  1. _make_attachment_part函数内部,使用encoders模块对有效负载进行编码.
  1. Inside your _make_attachment_part function, encode your payload using the encoders module.

def _make_attachment_part(self, filename: str) -> MIMEBase:
    content_type, encoding = mimetypes.guess_type(filename)
    if content_type is None or encoding is not None:
        content_type = "application/octet-stream"

    main_type, sub_type = content_type.split("/", 1)
    msg = MIMEBase(main_type, sub_type)
    with open(filename, "rb") as f:
        msg.set_payload(f.read())

    encoders.encode_base64(msg) # NEW

    base_filename = os.path.basename(filename)
    msg.add_header("Content-Disposition", "attachment", filename=base_filename)

    return msg

这篇关于.zip文件在通过gmail api发送并通过zlib压缩后被损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆