尝试将S3存储桶对接Lambda函数时出现BadZipFile错误该如何解决?
问题根因与修复方案
1. 核心逻辑错误
你当前的代码是尝试读取S3上已有的对象作为zip文件解压,但你并没有先完成「将S3文件打包为zip」的步骤,你读取的fileObject对应的S3对象本身就不是合法的zip格式,自然会触发BadZipFile报错。你之前尝试修改对象后缀名的操作没有意义,S3对象的后缀不影响文件本身的二进制内容格式。
2. 正确的打包实现(将S3多个文件打包为zip存回S3)
如果你是要实现S3文件打包为zip的需求,参考修复后的代码:
import boto3 import io import zipfile import json def handler(event, context): s3_resource = boto3.resource('s3') bucket_name = "替换为你的桶名" # 要打包的S3文件路径列表,可根据业务逻辑自定义生成规则 source_file_keys = ["test1.txt", "img/test2.jpg", "doc/test3.docx"] # 打包后zip文件在S3的存储路径 output_zip_key = "packaged_result.zip" # 初始化内存缓存和zip写入对象 buffer = io.BytesIO() with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf: for key in source_file_keys: # 读取S3单文件内容 obj = s3_resource.Object(bucket_name, key) file_content = obj.get()["Body"].read() # 写入zip包 zf.writestr(key, file_content) # 重置缓存指针到起始位置,否则上传的zip为空文件 buffer.seek(0) # 上传完成的zip包到S3 s3_resource.Object(bucket_name, output_zip_key).put(Body=buffer) return { 'statusCode': 200, 'body': json.dumps('Zip打包完成') }
3. 若你是要解压S3上已有的zip文件,排查以下问题
- 先手动下载
fileObject对应的S3对象到本地,用解压工具打开确认是合法的zip格式 - 读取S3对象后可打印前4个字节校验:合法zip文件的前4个字节固定为
PK\x03\x04,如果输出不符说明读取的对象不是zip格式 - 检查Lambda执行角色的S3读取权限,避免读取到的是权限报错的空内容或错误响应内容
- 原有代码存在解压文件覆盖原zip的问题:解压后的文件上传时用了和原zip相同的
Key=fileObject,会直接覆盖原文件,需要修改为对应的解压后文件存储路径
内容的提问来源于stack exchange,提问作者helpaccount321
相关产品推荐
相关产品推荐

