AWS Python Lambda返回S3中.tar.gz文件遇格式问题求助
解决AWS Lambda代理S3返回tar.gz文件损坏的问题
我来帮你搞定这个问题!你现在遇到的核心问题是错误地用文本编码逻辑处理二进制的tar.gz文件,导致原始字节流被篡改,所以解压时才会提示“不是gzip格式”。
问题出在哪?
你用codecs.open并指定encoding='utf-8'来读取文件,哪怕加了errors='ignore',这本质上是把二进制的tar.gz文件当作UTF-8文本解析——这种操作会破坏原始的二进制数据,因为二进制文件里的很多字节并不符合UTF-8编码规则,被忽略或替换后,文件自然就损坏了。
另外,其实你完全没必要把文件下载到/tmp再读取,直接从S3返回的对象体里拿原始二进制数据就行,既高效又能避免本地文件操作的坑。
修正后的代码
import boto3 def lambda_handler(event, context): s3_client = boto3.client('s3') bucket_name = "your-target-bucket" # 替换成你的S3桶名 # 这里根据你API Gateway的参数获取方式调整,比如从路径参数取文件key file_key = event['pathParameters'].get('file_key') try: # 直接获取S3对象的原始二进制数据 s3_response = s3_client.get_object(Bucket=bucket_name, Key=file_key) file_content = s3_response['Body'].read() response_headers = { 'Content-Type': s3_response['ContentType'], 'Content-Disposition': f'attachment; filename="{file_key.split("/")[-1]}"' } # 关键:Lambda返回二进制数据必须设置isBase64Encoded为True return { 'statusCode': 200, 'headers': response_headers, 'body': file_content, 'isBase64Encoded': True } except Exception as err: return { 'statusCode': 404, 'body': f"无法获取文件:{str(err)}" }
几个关键注意事项
- 绝对不要用文本模式处理二进制文件:tar.gz是纯二进制格式,要么用
open(..., 'rb')(不指定encoding)读取本地文件,要么直接用S3响应体的read()拿原始字节,绝对不能碰文本编码相关的设置。 - Lambda返回二进制的必填项:用API Gateway代理集成时,Lambda返回二进制数据必须设置
isBase64Encoded: True,否则API Gateway会把字节当作UTF-8文本处理,直接导致文件损坏。 - 跳过本地文件操作:直接读取S3的
Body比下载到/tmp再读取更高效,还能减少磁盘IO带来的潜在问题。
测试验证
改完代码重新部署后,再用wget下载文件并解压:
$ wget -v https://<apigfqdn>/release/simple/<package>/<package>-1.0.4.tar.gz $ tar -xzf <package>-1.0.4.tar.gz
这次应该能正常解压,不会再出现gzip格式错误了。
内容的提问来源于stack exchange,提问作者asdf
相关产品推荐
相关产品推荐

