如何使用Python boto3获取AWS S3中所有层级子目录(排除文件)
AWS S3 递归获取指定前缀下所有子目录方案
核心原理
S3 是对象存储服务,不存在真实的文件系统目录结构,所有「目录」本质上是对象键名的公共前缀,结合Delimiter="/"参数可按层级拆分前缀,递归查询即可获取任意深度的子目录。
方案1:获取全层级子目录列表
通过递归遍历每一层的公共前缀,收集所有层级的子目录路径:
async def get_all_subfolders(self, bucket, prefix): subfolders = set() result = await self.s3_client.list_objects( Bucket=bucket, Prefix=prefix, Delimiter="/" ) # 收集当前层级的子目录 current_prefixes = result.get("CommonPrefixes", []) for content in current_prefixes: current_p = content.get("Prefix") subfolders.add(current_p) # 递归查询当前子目录下的更深层级目录 child_folders = await self.get_all_subfolders(bucket, current_p) subfolders.update(child_folders) return subfolders
调用时直接传入初始前缀即可,返回结果就是全层级子目录集合。
方案2:获取仅存放文件的末级目录(最优结果)
如果只需要有文件存在的上一级目录,可在递归时同时判断当前前缀下是否存在非目录对象(即文件),存在则记录当前前缀:
async def get_file_parent_folders(self, bucket, prefix): parent_folders = set() result = await self.s3_client.list_objects( Bucket=bucket, Prefix=prefix, Delimiter="/" ) # 检查当前前缀下是否有文件,有则当前前缀就是文件的父目录 contents = result.get("Contents", []) # 若存在以/结尾的目录占位对象,可添加过滤条件:[c for c in contents if not c["Key"].endswith("/")] if contents: parent_folders.add(prefix) # 继续递归查询子目录 current_prefixes = result.get("CommonPrefixes", []) for content in current_prefixes: current_p = content.get("Prefix") child_folders = await self.get_file_parent_folders(bucket, current_p) parent_folders.update(child_folders) return parent_folders
补充说明
- 若目录数量超过1000条,
list_objects会返回截断标记IsTruncated,需要配合ContinuationToken循环拉取完整结果,补充分页逻辑即可。 - 推荐使用AWS官方更新的
list_objects_v2接口替代老旧的list_objects接口,调用参数基本兼容,性能和稳定性更好。
内容的提问来源于stack exchange,提问作者KZiovas
相关产品推荐
相关产品推荐

