如何用Python3以wb+分块写入大型EmailMessage对象?
分块写入大型EmailMessage对象的可行方案
直接调用EmailMessage.as_bytes()会一次性将整个邮件对象转换为字节串,对超大邮件来说,这种方式会占用大量内存,进而导致进程卡住、产生僵尸进程。要实现类似分块读写的效果,可以通过以下方法解决:
推荐方案:使用BytesGenerator分块写入
Python的email.generator.BytesGenerator可以逐步生成邮件的字节内容,并直接写入文件,无需一次性加载全部内容到内存。
示例代码:
from email.generator import BytesGenerator with open(complete_path, 'wb+') as fp: # 初始化BytesGenerator,绑定目标文件对象 generator = BytesGenerator(fp, maxheaderlen=0) # 分块生成并写入邮件内容 generator.flatten(msg, unixfrom=False)
原理说明
BytesGenerator.flatten()方法会遍历EmailMessage的结构(邮件头部、正文、附件等),逐段生成字节数据并写入绑定的文件对象,从根源上避免了超大字节串占用内存的问题,完美替代你想要的分块读写逻辑。
备选方案:自定义分块生成器
如果需要更精细控制分块大小,可以通过内存缓冲区中转后分块读取,但这种方式不如直接写入高效,仅推荐在特殊场景下使用:
from email.generator import BytesGenerator from io import BytesIO def get_email_chunks(msg, chunk_size=1024): bio = BytesIO() generator = BytesGenerator(bio, maxheaderlen=0) generator.flatten(msg, unixfrom=False) bio.seek(0) while True: chunk = bio.read(chunk_size) if not chunk: break yield chunk # 分块写入文件 with open(complete_path, 'wb+') as fp: for chunk in get_email_chunks(msg, 1024): fp.write(chunk)
错误代码说明
你最初尝试调用msg.read(1024)是错误的,因为EmailMessage是内存中的邮件结构对象,并非可读取的字节流对象,本身不存在read()方法,必须通过生成器类来转换输出内容。
内容的提问来源于stack exchange,提问作者user956424
相关产品推荐
相关产品推荐

