问题描述
如果我具有以下目录结构,并且前缀为/ folder1,
/folder1/folder11/folder12/folder13/*.files
/folder21/folder22/folder23/*.files
/folder31/folder32/*.files
我想动态遍历这些目录,以便分别读取每个叶子文件夹中的文件,即,我需要一个列表
[
/folder1/folder11/folder12/folder13/,/folder1/folder21/folder22/folder23/,/folder1/folder31/folder32/
]
除了递归遍历每个前缀,获取下一级前缀,连接,获取下一级等,直到到达最后一个(叶子)文件夹,还有其他更好的方法吗?
解决方法
列出来自Amazon S3的对象时,如果您指定Delimiter='/'
,则它将返回CommonPrefixes
的列表。这实际上是给定Prefix
的子目录列表。
但是,我建议您不要考虑目录。相反,只需遍历所有对象并查看Key
即可知道对象的路径。
如果只需要包含文件的路径列表,请使用以下命令:
import boto3
BUCKET = 'my-bucket'
s3_resource = boto3.resource('s3')
folders = set()
# Find paths of all non-empty objects (to exclude zero-length 'folder' objects)
for object in s3_resource.Bucket(BUCKET).objects.all():
if object.size > 0 and '/' in object.key:
folders.add(object.key[:object.key.rfind('/')])
print (folders)
,
生成S3 inventory report并使用Athena处理数据。该报告的Athena表结构也在同一AWS文章中提到。这是无服务器的方法。
,您可以在循环中使用它来获取前缀
def get_list_of_prefixes_from_prefix(bucket,prefix):
"""gets list of prefixes for given bucket and prefix"""
list_of_prefixes = []
paginator = boto3.resource('s3').meta.client.get_paginator('list_objects')
for result in paginator.paginate(Bucket=bucket,Prefix=prefix,Delimiter='/'):
# print(result)
if 'CommonPrefixes' in result:
prefixes = [f['Prefix'] for f in result['CommonPrefixes']]
list_of_prefixes.extend(prefixes)
return list_of_prefixes
list_of_prefixes = get_list_of_prefixes_from_prefix('my-bucket','my-prefix/')
,
import boto3
list_of_prefixes = []
def get_list_of_prefixes(bucket,prefix):
global list_of_prefixes
paginator = boto3.resource('s3').meta.client.get_paginator('list_objects')
for result in paginator.paginate(Bucket=bucket,Delimiter='/'):
if 'CommonPrefixes' in result:
for f in result['CommonPrefixes']:
get_list_of_prefixes(bucket,f['Prefix'])
else:
list_of_prefixes.append(prefix)
return list_of_prefixes
list_of_prefixes = get_list_of_prefixes('my-bucket','my-prefix/')
for i in list_of_prefixes:
print(i)