【问题标题】:How to download multiple files having same prefix as filename from various folders of S3 bucket?如何从 S3 存储桶的各个文件夹中下载与文件名具有相同前缀的多个文件?
【发布时间】:2018-06-05 13:26:02
【问题描述】:

假设我有一个名为 bucketSample 的 S3 存储桶。

我有不同的文件夹,例如 abcdefxyz

现在我在上述所有文件夹中都有多个前缀为 hij_ 的文件。

我想下载所有前缀为hij_ 的文件。 (例如hij_qwe.txthij_rty.pdf等)

我已经通过各种方式,但对于GetObject,我必须提供具体的对象名称,我只知道前缀。

使用 TransferManager 我可以下载文件夹 abc 的所有文件,但不能下载具有特定前缀的文件。

那么有什么方法可以只下载前缀为hij_的所有文件?

【问题讨论】:

  • 如果您使用的是 TransferManager 的 downloadDirectory() 方法,那么您应该能够将 keyPrefix 设置为 abc/hij_ 并且它将下载具有该键前缀的所有对象。键前缀不必以文件夹名称结尾(S3 不是带有文件夹和文件的常规分层文件系统)。
  • 非常感谢@jarmod,它成功了。但它也创建了相同的层次结构 abc/hij_ ,但我可以只下载没有层次结构的文件(文件夹结构),因为我的 abc 文件夹位于层次结构中太深,如 (bucket/qwe/rty/uio/... /abc),如果有什么方法可以实现,请告诉我。
  • 您可以指定一个本地destinationDirectory,但我相信TransferManager 将始终根据您的密钥层次结构创建子文件夹。没有其他任何意义。当然,您可以在之后移动文件。

标签: java amazon-web-services amazon-s3 aws-sdk awss3transfermanager


【解决方案1】:
public void getFiles(final Set<String> bucketName, final Set<String> keys, final Set<String> prefixes) {
    try {
        ObjectListing objectListing = s3Client.listObjects(bucketName); //lists all the objects in the bucket
        while (true) {
            for (Iterator<?> iterator = objectListing.getObjectSummaries().iterator();
                 iterator.hasNext(); ) {
                S3ObjectSummary summary = (S3ObjectSummary) iterator.next();
                for (String key : keys) {
                    for (String prefix : prefixes)
                        if (summary.getKey().startsWith(key + "/" prefix)) {
                            //HERE YOU CAN GET THE FULL KEY NAME AND HENCE DOWNLOAD IT IN NEW FILE USING THE TRANFER MANAGER
                        }
                    }
                }
            }
            if (objectListing.isTruncated()) {
                objectListing = s3Client.listNextBatchOfObjects(objectListing);
            } else {
                break;
            }
        }
    } catch (AmazonServiceException e) { }
}

在此处了解 AWS 目录结构:How does AWS S3 store files? (directory structure)

因此,对于您的用例,键 + “/” + 前缀充当存储在 S3 存储桶中的对象的前缀。通过比较前缀将S3 Bucket中的所有对象,可以得到完整的键名。

【讨论】:

  • 这里的key 是什么意思? accesskeysecretkey?
【解决方案2】:

使用 python,您可以使用 boto3 库,我发现它对解决类似情况非常有用。

示例代码:

import boto3
import os

KEY = ''
SECRET = ''
download_folder = os.path.join(os.path.expanduser('~'), 'Downloads')
bucket = 'bucketSample'
folders = ['abc', 'def', 'xyz']
prefixes = ['hij_']

try:
    # Needed for the pagination method in order to get objects with certain prefixes instead of iterating over all objects, you should get the aws_access_key_id and aws_secret_access_key for your bucket if available
    s3 = boto3.resource(
        's3',
        aws_access_key_id=KEY,
        aws_secret_access_key=SECRET)

    # Needed for the download method, you should get the aws_access_key_id and aws_secret_access_key for your bucket if available
    client = boto3.client(
        's3',
        aws_access_key_id=KEY,
        aws_secret_access_key=SECRET)

    # Get paginated objects
    paginator = client.get_paginator('list_objects')

    for folder in folders:
        for file_prefix in prefixes:
            prefix = folder + file_prefix
            page_iterator = paginator.paginate(Bucket=bucket, Prefix=prefix)

            if page_iterator:
                for page in page_iterator:
                    if 'Contents' in page:
                        for content in page['Contents']:
                            file_path = os.path.join(download_folder, content['Key'])
                            s3.meta.client.download_file(bucket, str(content['Key']), file_path)
except:
    print('An error occurred')

【讨论】:

    猜你喜欢
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多