使用Python Boto3上传Zip文件至S3异常:上传文件仅18KB
解决Boto3上传S3时zip文件大小异常(仅18KB)的问题
你说用Python的Boto3把邮件压缩后的zip文件上传到S3,但实际传上去的只有18KB,远小于预期?这种情况我之前排查过类似的,大概率是压缩环节出了问题,或者上传时没正确指向生成的zip文件,给你一步步拆解排查和解决的思路:
第一步:先确认本地压缩文件是否正常
18KB的大小非常像一个空的或不完整的zip包,先别着急看S3,先检查本地生成的文件:
- 手动打开你的项目目录,找到那个zip文件,看看它的实际大小和内容,如果本地文件本身就只有18KB,那问题完全出在邮件下载或压缩步骤,和S3上传无关。
- 可以在压缩代码后加一段校验代码,快速确认:
zip_file_path = "你生成的zip文件名.zip" if os.path.exists(zip_file_path): print(f"本地zip文件大小:{os.path.getsize(zip_file_path)/1024:.2f} KB") else: print("压缩后的zip文件根本没生成!")
常见的压缩环节问题
如果本地文件确实异常,那大概率是压缩逻辑有问题:
- 如果你用的是
shutil.make_archive:要确认参数里的根目录和待压缩文件路径是否正确,比如是不是只指定了空目录,或者漏选了下载的邮件文件。 - 如果你用的是
zipfile模块:检查是不是没把所有下载的邮件都添加到zip里,比如循环遍历邮件文件时出了错,导致只创建了一个空的zip容器(空zip的大小刚好就是十几KB)。
上传环节的排查点
如果本地zip文件是正常的,那再看S3上传的逻辑:
- 检查上传时指定的文件路径是不是和本地生成的zip路径完全一致?有没有拼写错误(比如大小写、后缀名写错,或者指向了其他临时文件)。
- 确认你的Boto3上传代码有没有等待压缩完成就执行?比如压缩是耗时操作,但代码没等压缩完成就触发了上传,导致传了一个还在写入的不完整文件。
- 给你一个标准的上传代码示例,你可以对比自己的代码:
import boto3 s3_client = boto3.client('s3') bucket_name = "你的S3存储桶名称" local_zip_path = "正确的本地zip文件路径.zip" s3_save_key = "S3上要保存的路径/文件名.zip" try: s3_client.upload_file(local_zip_path, bucket_name, s3_save_key) print(f"文件已成功上传到S3:s3://{bucket_name}/{s3_save_key}") except FileNotFoundError: print("报错:要上传的本地文件不存在!") except Exception as e: print(f"上传出错:{str(e)}")
完整的压缩+上传参考片段
你可以对比自己的代码,看看哪里有差异:
import zipfile import os import boto3 # 假设下载的邮件都存在mail_files目录下 mail_dir = "./mail_files" zip_filename = "all_user_mails.zip" # 压缩邮件文件(确保所有邮件都被加入) with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: for root, _, files in os.walk(mail_dir): for file in files: file_full_path = os.path.join(root, file) # 保留邮件的相对路径,避免在zip里生成冗余目录 zipf.write(file_full_path, os.path.relpath(file_full_path, mail_dir)) # 校验本地文件 if not os.path.exists(zip_filename): print("压缩失败,文件未生成") exit(1) print(f"压缩完成,本地文件大小:{os.path.getsize(zip_filename)/1024:.2f} KB") # 上传到S3 s3 = boto3.client('s3') bucket_name = "your-bucket-name" s3_key = "mail-backups/all_user_mails.zip" try: s3.upload_file(zip_filename, bucket_name, s3_key) print("上传S3成功!") except Exception as e: print(f"上传失败:{str(e)}")
先从本地文件校验开始排查,一般很快就能找到问题所在。
内容的提问来源于stack exchange,提问作者davidb
相关产品推荐
相关产品推荐

