2015-06-23 84 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