S3的list_objects_v2返回递归目录无报错,如何实现路径不存在时抛异常?
解决方案
S3本身没有真实的文件夹结构,所有存储的都是对象键,list_objects_v2的Prefix参数是前缀匹配逻辑,所以会返回所有以folder/10开头的对象(比如folder/100)。要实现“目标路径不存在时抛异常”,需要精确校验路径对应的对象或虚拟文件夹是否存在,具体分两种场景处理:
场景1:检查folder/10作为单个对象是否存在
如果folder/10是一个具体的文件对象,直接用head_object接口做精确校验,不存在时抛出异常:
import boto3 from botocore.exceptions import ClientError s3 = boto3.client('s3') bucket = 'my_bucket' target_key = 'folder/10' # 精确校验目标对象是否存在 try: s3.head_object(Bucket=bucket, Key=target_key) except ClientError as e: if e.response['Error']['Code'] == '404': # 对象不存在,抛出自定义异常 raise ValueError(f"存储桶 {bucket} 中不存在路径 {target_key}") from e # 其他AWS服务错误直接抛出 raise # 确认存在后再执行递归列表查询 contents = s3.list_objects_v2(Bucket=bucket, Prefix=target_key) print(contents.get('Contents'))
场景2:检查folder/10作为虚拟文件夹是否存在
如果folder/10是一个虚拟文件夹(期望该路径下有子对象或子文件夹),需要结合Delimiter='/'获取直接子项,同时校验是否存在标记文件夹的空对象(部分工具会创建folder/10/这样的空对象来标识文件夹):
import boto3 from botocore.exceptions import ClientError s3 = boto3.client('s3') bucket = 'my_bucket' target_prefix = 'folder/10' # 获取目标前缀下的直接子项(不递归) response = s3.list_objects_v2(Bucket=bucket, Prefix=target_prefix, Delimiter='/') # 检查是否存在目标前缀对应的对象,或有直接子内容 path_exists = False # 检查是否存在名为target_prefix的对象 try: s3.head_object(Bucket=bucket, Key=target_prefix) path_exists = True except ClientError as e: if e.response['Error']['Code'] != '404': raise # 检查是否有直接子对象(Contents)或子文件夹(CommonPrefixes) if not path_exists: path_exists = bool(response.get('Contents')) or bool(response.get('CommonPrefixes')) if not path_exists: raise ValueError(f"存储桶 {bucket} 中不存在路径 {target_prefix}") # 确认存在后执行递归列表查询 contents = s3.list_objects_v2(Bucket=bucket, Prefix=target_prefix) print(contents.get('Contents'))
关键说明
head_object是精确匹配对象键的接口,比list类接口更高效,适合单独对象的存在性校验。Delimiter='/'会让list_objects_v2只返回目标前缀下的直接子项,不会递归匹配更长的前缀(比如folder/100)。
内容的提问来源于stack exchange,提问作者der_radler
相关产品推荐
相关产品推荐

