将文件列在AWS S3存储桶的特定"文件夹"中

dav*_*ooh 44 java amazon-s3 amazon-web-services

我需要列出我的S3存储桶中包含的某个文件夹中包含的所有文件.

文件夹结构如下

/my-bucket/users/<user-id>/contacts/<contact-id>
Run Code Online (Sandbox Code Playgroud)

我有与用户相关的文件和与某个用户的联系人相关的文件.我需要列出两者.

要列出我正在使用此代码的文件:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName("my-bucket")
                .withPrefix("some-prefix").withDelimiter("/");
ObjectListing objects = transferManager.getAmazonS3Client().listObjects(listObjectsRequest);
Run Code Online (Sandbox Code Playgroud)

要列出某个用户的文件我正在使用此前缀:

users/<user-id>/

我正确地获取目录中的所有文件,不包括contacts子目录,例如:

users/<user-id>/file1.txt
users/<user-id>/file2.txt
users/<user-id>/file3.txt
Run Code Online (Sandbox Code Playgroud)

要列出某个用户联系人的文件而不是我使用此前缀:

users/<user-id>/contacts/<contact-id>/

但在这种情况下,我也将目录本身作为返回的对象:

users/<user-id>/contacts/<contact-id>/file1.txt
users/<user-id>/contacts/<contact-id>/file2.txt
users/<user-id>/contacts/<contact-id>/
Run Code Online (Sandbox Code Playgroud)

为什么我会出现这种行为?两个上市要求之间有什么不同?我只需要列出目录中的文件,不包括子目录.

Vic*_*c K 28

虽然每个人都说s3中没有目录和文件,但只有对象(和存储桶),这是绝对正确的,我建议利用答案中描述的CommonPrefixes .因此,您可以执行以下操作以获取"文件夹"(commonPrefixes)和"文件"(objectSummaries)的列表:

ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucket.getName()).withPrefix(prefix).withDelimiter(DELIMITER);
ListObjectsV2Result listing = s3Client.listObjectsV2(req);
for (String commonPrefix : listing.getCommonPrefixes()) {
        System.out.println(commonPrefix);
}
for (S3ObjectSummary summary: listing.getObjectSummaries()) {
    System.out.println(summary.getKey());
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,对于objectSummaries(文件),它应该返回(如果前缀正确):
users/user-id/contacts/contact-id/file1.txt
users/user-id/contacts/contact-id/file2.txt

for commonPrefixes:
users/user-id/contacts/contact-id /

  • 在这里查看这篇文章,似乎这正是您在寻找的内容:http://codeflex.co/get-list-of-objects-from-s3-directory/ (2认同)

Mat*_*ser 25

S3中的所有东西都是一个对象.对您而言,它可能是文件和文件夹.但对于S3来说,它们只是对象.

以分隔符结尾的对象(/在大多数情况下)通常被视为文件夹,但情况并非总是如此.这取决于应用程序.同样,在您的情况下,您将其解释为文件夹.S3不是.这只是另一个对象.

在上面的例子中,对象users/<user-id>/contacts/<contact-id>/作为一个独特的对象存在于S3中,但对象users/<user-id>/却没有.这是你的回答中的差异.为什么他们是这样的,我们不能告诉你,但有人在一个案件中制造了这个对象,而在另一个案件中却没有.您在AWS管理控制台中看不到它,因为控制台将其解释为文件夹并将其隐藏.

由于S3只是将这些东西视为对象,因此它不会"排除"某些东西.客户端应该处理对象,因为它们应该被处理.

你的解决方案

由于您是不想要文件夹对象的人,因此您可以通过检查a的最后一个字符来自己排除它/.如果是,则忽略响应中的对象.


Nah*_*grc 5

如果您的目标只是获取文件而不是文件夹,那么我采取的方法是使用文件size作为过滤器。此属性是 AWS 托管的文件的当前大小。所有文件夹在该属性中都返回 0。以下是使用 linq 的 C# 代码,但翻译成 Java 应该不难。

var amazonClient = new AmazonS3Client(key, secretKey, region);
var listObjectsRequest= new ListObjectsRequest
            {
                BucketName = 'someBucketName',
                Delimiter = 'someDelimiter',
                Prefix = 'somePrefix'
            };
var objects = amazonClient.ListObjects(listObjectsRequest);
var objectsInFolder = objects.S3Objects.Where(file => file.Size > 0).ToList();
Run Code Online (Sandbox Code Playgroud)

  • 一个合理的答案,尽管我的纯粹主义者说文件就是文件,即使它是零字节。文件名不能以“/”结尾并且文件名长度不能为零 - 我认为它们是比大小更好的决策者 (5认同)