列出 AWS S3 存储桶的特定“文件夹”中的文件

2022-08-31 10:52:14

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

文件夹结构如下

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

我有与用户相关的文件和与特定用户联系人相关的文件。我需要列出两者。

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

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

要列出某个用户的文件,我使用以下前缀:

users/<user-id>/

并且我正确地获取了目录中除子目录之外的所有文件,例如:contacts

users/<user-id>/file1.txt
users/<user-id>/file2.txt
users/<user-id>/file3.txt

要列出某个用户联系人的文件,我使用以下前缀:

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>/

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


答案 1

虽然每个人都说s3中没有目录和文件,只有对象(和桶),这是绝对正确的,但我建议利用这个答案中描述的CommonPrefixes。因此,您可以执行以下操作来获取“文件夹”(commonPrefixes)和“files”(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());
}

在你的例子中,对于 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/

参考资料: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html


答案 2

S3 中的所有内容都是一个对象。对您来说,它可能是文件和文件夹。但对于S3来说,它们只是对象。

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

在上面的示例中,对象在 S3 中作为不同的对象存在,但该对象不存在。这就是你回答的差异。为什么他们会这样,我们不能告诉你,但是有人在一种情况下做了这个物体,而在另一种情况下却没有。您在 AWS 管理控制台中看不到它,因为控制台会将其解释为文件夹并将其隐藏给您。users/<user-id>/contacts/<contact-id>/users/<user-id>/

由于S3只是将这些东西视为对象,因此它不会为您“排除”某些内容。这取决于客户来处理对象,因为它们应该被处理。

您的解决方案

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


推荐