使用boto3从S3下载pkl文件自动添加哈希后缀报错如何解决
后缀产生原因
带随机哈希后缀的文件是boto3依赖的s3transfer模块的分片下载机制生成的临时中间文件:
- 默认当下载文件大小超过8MB时,s3transfer会自动启动分片下载,将下载的分片先写入带随机哈希后缀的临时文件中
- 全部分片下载完成且校验通过后,临时文件会被重命名为你指定的目标文件名
- 本次报错是因为你指定的目标文件所在的本地父目录不存在,s3transfer不会自动创建父目录,导致临时文件创建失败直接抛出
FileNotFoundError,没有走到最终重命名为正式文件的步骤
修复方案
- 核心修复:下载文件前先递归创建目标文件所在的父目录,修改后代码示例如下:
import boto3 import os s3_conn = boto3.session.Session(profile_name=profile).client('s3') for each in range(len(keys)): key = keys[each] prefix = file_prefix[each] file_name = prefix + key.split('/')[-1] target_file_path = os.path.join(target_dir, file_name) # 递归创建父目录,exist_ok=True表示目录已存在时不报错 os.makedirs(os.path.dirname(target_file_path), exist_ok=True) s3_conn.download_file(bucket_name, key, target_file_path)
- 可选优化:如果你的文件普遍体积较小,不想触发分片下载的临时文件逻辑,可以调整分片阈值,或者直接用
get_object接口直接写文件:
# 方案1:调整分片阈值为1GB,小于1GB的文件不会生成临时文件 from boto3.s3.transfer import TransferConfig config = TransferConfig(multipart_threshold=1024 * 1024 * 1024) s3_conn.download_file(bucket_name, key, target_file_path, Config=config) # 方案2:直接用get_object下载,完全绕过临时文件机制 s3_resp = s3_conn.get_object(Bucket=bucket_name, Key=key) with open(target_file_path, 'wb') as f: f.write(s3_resp['Body'].read())
内容的提问来源于stack exchange,提问作者el abed houssem
相关产品推荐
相关产品推荐

