【问题标题】:Zip sent via email is invalid on first attempt通过电子邮件发送的 Zip 在第一次尝试时无效
【发布时间】:2015-09-09 11:07:24
【问题描述】:

我尝试创建一个包含来自特定目录(和子目录)的所有文件的 zip 存档并通过邮件发送:

#Create archive containing all files from directory "reports/"
zipf = zipfile.ZipFile('reports.zip', 'w')
for root, dirs, files in os.walk('reports/'):
for file in files:
    zipf.write(os.path.join(root, file))

#Create email
msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = "Monatliche Reports - Verrechnung an Kunden"

#Attach report.zip to email
fp = open(fileToSend, "rb")
attachment = MIMEBase('application', 'zip')
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment",
filename=fileToSend)
msg.attach(attachment)

#Send email via localhost smtp-server
server = smtplib.SMTP("localhost")
server.sendmail(emailfrom, emailto, msg.as_string())
server.quit()

脚本似乎有效。我收到了包含所有文件的附加 zip 存档的邮件。脚本执行时有两种可能的情况:

案例 1:在执行脚本之前已经有一个 zip 存档,名为 report.zip(上次运行的旧文件)

案例2:执行脚本前没有zip压缩包。

如果情况 1 一切正常。旧的替换为新生成的,然后将通过电子邮件发送。

在案例 2 中,report.zip 生成并通过电子邮件发送,但它是无效的。如果我尝试使用 7zip(或 Windows 板载工具)在 Windows 上打开它,它只会说“存档无效”。我发现只有通过电子邮件发送的 report.zip 被破坏了。如果我通过电子邮件手动发送案例 2 中生成的 report.zip,我可以将其解压缩并使用这些文件。

我是一个 python 新手,老实说,要达到我现在的位置已经够难了,但是解决这个问题让我很头疼。谁能解释一下我做错了什么?

【问题讨论】:

    标签: python email python-3.x mime-types mime


    【解决方案1】:

    您需要在添加文件后关闭 zip 文件以确保存档完整。

    https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.close

    最好使用with 声明:

    with zipfile.ZipFile('reports.zip', 'w') as zipf: 
       for root, dirs, files in os.walk('reports/'):
          for file in files:
             zipf.write(os.path.join(root, file))    
    

    详情 据我了解。

    第一次运行

    • zipfile 创建文件描述符(在内存占位符中)和包清单(要添加的文件)
    • zipfile.write() 将文件压缩到文件描述符中,并将文件添加到清单中
    • msg.attach() 文件尚未刷新,因此内存中的位置没有任何内容。
    • --结束脚本文件描述符清理将文件描述符刷新到磁盘。 (reports.zip 存在但不完整/无效)

    第二次运行

    • zipfile 创建一个 fd 和 manifest
    • zipfile.write() 将文件压缩到 fd 并将文件添加到清单中
    • msg.attach() 文件上次刷新但仍不完整附加无效文件

    【讨论】:

    • Thx 这确实解决了问题,但我仍然对它在我的代码的第二次尝试中起作用感到困惑。为什么存档在第 2 次运行时要关闭,而在第一次尝试时保持打开状态?
    • 因为当脚本完成时解释器会关闭文件。在第二次尝试时,它将获得(部分)文件。 zip 文件在第一遍结束时仍处于打开状态并准备好接收更多文件,这将是一个不完整的包。
    • 所以第一次尝试它是一个不完整的包,因为当脚本完成执行时文件仍然打开?我看不出尝试 2 的区别。发生的情况完全相同,文件在脚本完成时也是打开的。非常感谢您的解释。
    【解决方案2】:

    试试这个:

    import yagmail
    me = 'me@gmail.com'
    yag = yagmail.SMTP(emailfrom, 'mypassword') 
    yag.send(emailto,  "Monatliche Reports - Verrechnung an Kunden", 'reports.zip')
    

    您可能必须使用 pip install yagmail 安装 yagmail

    免责声明:我是 yagmail 的开发者,该软件包试图让发送电子邮件(带或不带附件)变得容易。

    【讨论】:

    • 看起来很有趣,我会试一试。谢谢你的提示
    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2022-01-18
    • 2015-12-16
    • 2014-09-20
    相关资源
    最近更新 更多