无法复制名称含特殊字符的S3文件,报404错误如何解决?
解决S3含特殊字符文件复制时的404错误
你的代码核心问题并非特殊字符导致,而是错误截断了S3对象的完整Key路径: s3_objects["Key"]是对象的完整路径(比如v2/abc/date=2022-12-28/subfolder/Stat@2022-12-28@nameflyer@@_1672185644223109701__i-008f78f00fd9d9bfb.parquet),但你用split("/")[4]只提取了最后的文件名,导致复制时S3找不到对应路径的对象,返回404。
修正后的代码
def copy_object(): import os import boto3 # 初始化源S3客户端 s3 = boto3.client('s3', region_name='us-east-1') source_bucket = os.environ.get('bucket') prefix = f'v2/abc/date={date}' response = s3.list_objects_v2(Bucket=source_bucket, Prefix=prefix) for s3_obj in response["Contents"]: # 直接使用完整的对象Key,不要截断路径 full_key = s3_obj["Key"] print(full_key) copy_source = { 'Bucket': source_bucket, 'Key': full_key } # 建议将客户端初始化移到循环外,避免重复创建实例 s3_dist = boto3.resource( service_name=os.environ.get('serviceName'), region_name=os.environ.get('regionName'), aws_access_key_id=os.environ.get('awsAccessKeyId'), aws_secret_access_key=os.environ.get('awsSecretAccessKey') ) # 目标Key可选:保留完整路径 或 仅保留文件名(用os.path.basename(full_key)) dest_key = full_key ack = s3_dist.meta.client.copy(copy_source, 'dest_bucket', dest_key)
补充说明
- 特殊字符处理:Boto3会自动处理S3对象Key中的特殊字符(如
@、__等)的URL编码,无需手动转义,只要保证使用完整正确的Key即可。 - 分页处理:如果存储桶内符合前缀的对象超过1000个,需要通过
ContinuationToken处理分页,否则会遗漏部分对象。 - 效率优化:将S3客户端的初始化逻辑移到循环外部,避免每次循环重复创建客户端实例。
内容的提问来源于stack exchange,提问作者Barun
相关产品推荐
相关产品推荐

