Python生成的zip文件本地可解压但上传至AWS S3后无法提取问题排查
问题根因与修复方案
首要故障原因
ZipFile 基于上下文管理器with的生命周期执行文件收尾逻辑,只有退出with代码块后,才会将zip格式要求的中央目录、结束标识符写入本地文件。当前代码将S3上传逻辑放在了with代码块内部,上传时读取的是未完全构造的残缺zip文件,因此S3存储的文件无法正常解压。
本地生成的zip可正常解压,是因为打开本地文件时with代码块已执行完毕,文件已完成最终写入。
其他可能诱因
- S3上传时未指定zip文件对应的MIME类型,部分客户端下载时会自动修改内容编码导致文件损坏,建议上传时补充
ContentType参数 - 运行环境磁盘IO缓存未主动刷新,也可能导致上传时读取到的文件内容不完整
修复代码示例
import urllib from zipfile import ZipFile import os medias = ['https://baby-staging-bucket.s3.us-east-2.amazonaws.com/asset/0002.jpg', 'https://baby-staging-bucket.s3.us-east-2.amazonaws.com/asset/2.png', 'https://baby-staging-bucket.s3.us-east-2.amazonaws.com/asset/02.png' ] for i in medias: file_name = i.split("/")[-1] urllib.urlretrieve(i, "media/"+file_name) # 构造zip文件 local_os_path = f'media/{title}.zip' with ZipFile(local_os_path, 'w') as zip: for file in medias: file_name = file.split("/")[-1] # 增加arcname参数避免解压后嵌套media目录 zip.write("media/"+file_name, arcname=file_name) os.remove("media/"+file_name) # 上传逻辑移到with块外部,确保zip文件完全写入后再上传 s3 = session.resource('s3') storage_path = f'asset/nfts/zip/{title}.zip' s3.meta.client.upload_file( Filename=local_os_path, Bucket=AWS_STORAGE_BUCKET_NAME, Key=storage_path, ExtraArgs={'ContentType': 'application/zip'} ) # os.remove(local_os_path) DesignerProduct.objects.filter(id=instance.id).update( zip_file_path=S3_BUCKET_URL + storage_path, )
内容的提问来源于stack exchange,提问作者soubhagya
相关产品推荐
相关产品推荐

