2015-06-23 79 views
0

无效我尝试从一个特定的目录(和子目录)包含所有文件的zip压缩文件,并通过电子邮件发送: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存档。当执行脚本有2种可能情况:

案例1:已经有一个zip压缩包执行脚本,命名为report.zip(旧上次运行)

案例2前:有在执行脚本之前没有zip存档。

在案例1中一切正常。旧的替换为新生成的,然后通过电子邮件发送。

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

我是一个蟒蛇新手,说实话,它已经很难达到我目前的地步,但解决这个问题让我头疼。任何人都可以解释我做错了什么吗?

回答

2

添加文件后需要关闭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.write()压缩文件到文件的描述符,并添加该文件到清单
  • msg.attach()该文件没有刷新,所以没有任何内容位置仍然存在。
  • - 结束脚本文件描述符清理将文件描述符刷新到磁盘。 (reports.zip存在,但不完整/无效)

第二次运行

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

Thx这确实解决了这个问题,但我仍然困惑,它对我的​​代码进行了第二次尝试。为什么档案应该在第一次尝试时保持打开状态时在第二次运行时关闭? – SaintCore

+1

,因为当脚本结束时,解释器将关闭文件。并在第二次尝试它会得到(部分)文件。在第一次传递结束时,zipfile仍然打开并准备好更多文件,并且将是一个不完整的包。 – corn3lius

+0

因此,这是一个不完整的软件包,因为在脚本完成执行时文件仍处于打开状态。我无法看到差异尝试2.发生完全相同的情况,文件在脚本完成时也处于打开状态。 非常感谢您的解释。 – SaintCore

0

试试这个:

import yagmail 
me = '[email protected]' 
yag = yagmail.SMTP(emailfrom, 'mypassword') 
yag.send(emailto, "Monatliche Reports - Verrechnung an Kunden", 'reports.zip') 

你可能会与pip install yagmail

免责声明安装yagmail:我的yagmail开发者,试图以方便发送电子邮件包(有或没有附件)。

+0

看起来很有趣,我会试试看。 Thx为你的提示 – SaintCore