如何获取S3存储桶中所有不同前缀的列表?

问题描述

如果我具有以下目录结构,并且前缀为/ 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)