Java 列出 AWS S3 存储桶的特定“文件夹”中的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38051789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listing files in a specific "folder" of a AWS S3 bucket
提问by davioooh
I need to list all files contained in a certain folder contained in my S3 bucket.
我需要列出 S3 存储桶中某个文件夹中包含的所有文件。
The folder structure is the following
文件夹结构如下
/my-bucket/users/<user-id>/contacts/<contact-id>
I have files related to users and files related to a certain user's contact. I need to list both.
我有与用户相关的文件和与某个用户的联系人相关的文件。我需要列出两者。
To list files I'm using this code:
要列出我正在使用此代码的文件:
ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName("my-bucket")
.withPrefix("some-prefix").withDelimiter("/");
ObjectListing objects = transferManager.getAmazonS3Client().listObjects(listObjectsRequest);
To list a certain user's files I'm using this prefix:
要列出某个用户的文件,我使用了这个前缀:
users/<user-id>/
users/<user-id>/
and I'm correctly getting all files in the directory excluding contacts
subdirectory, for example:
并且我正确地获取了目录中不包括contacts
子目录的所有文件,例如:
users/<user-id>/file1.txt
users/<user-id>/file2.txt
users/<user-id>/file3.txt
To list a certain user contact's files instead I'm using this prefix:
为了列出某个用户联系人的文件,我使用了这个前缀:
users/<user-id>/contacts/<contact-id>/
users/<user-id>/contacts/<contact-id>/
but in this case I'm getting also the directory itself as a returned object:
但在这种情况下,我还将目录本身作为返回对象获取:
users/<user-id>/contacts/<contact-id>/file1.txt
users/<user-id>/contacts/<contact-id>/file2.txt
users/<user-id>/contacts/<contact-id>/
Why am I getting this behaviour? What's different beetween the two listing requests? I need to list only files in the directory, excluding sub-directories.
为什么我会出现这种行为?这两个列表请求之间有什么不同?我只需要列出目录中的文件,不包括子目录。
采纳答案by Matt Houser
Everything in S3 is an object. To you, it may be files and folders. But to S3, they're just objects.
S3 中的一切都是对象。对您来说,它可能是文件和文件夹。但对 S3 来说,它们只是对象。
Objects that end with the delimiter (/
in most cases) are usually perceived as a folder, but it's not always the case. It depends on the application. Again, in your case, you're interpretting it as a folder. S3 is not. It's just another object.
以分隔符结尾的对象(/
在大多数情况下)通常被视为文件夹,但并非总是如此。这取决于应用程序。同样,在您的情况下,您将其解释为文件夹。S3 不是。这只是另一个对象。
In your case above, the object users/<user-id>/contacts/<contact-id>/
exists in S3 as a distinct object, but the object users/<user-id>/
does not. That's the difference in your responses. Why they're like that, we cannot tell you, but someone made the object in one case, and didn't in the other. You don't see it in the AWS Management Console because the console is interpreting it as a folder and hiding it from you.
在上面的例子中,该对象users/<user-id>/contacts/<contact-id>/
作为一个不同的对象存在于 S3 中,但该对象users/<user-id>/
不存在。这就是你的反应不同。为什么他们会这样,我们不能告诉你,但有人在一个案例中制造了这个物体,而在另一个案例中却没有。您在 AWS 管理控制台中看不到它,因为控制台将其解释为文件夹并将其隐藏起来。
Since S3 just sees these things as objects, it won't "exclude" certain things for you. It's up to the client to deal with the objects as they should be dealt with.
由于 S3 只是将这些东西视为对象,因此它不会为您“排除”某些东西。由客户来处理应该处理的对象。
Your Solution
您的解决方案
Since you're the one that doesn't want the folder objects, you can exclude it yourself by checking the last character for a /
. If it is, then ignore the object from the response.
由于您不想要文件夹对象,因此您可以通过检查最后一个字符的/
. 如果是,则忽略响应中的对象。
回答by Magnus
S3 does not have directories, while you can list files in a pseudo directory manner like you demonstrated, there is no directory "file" per-se.
You may of inadvertently created a data file called users/<user-id>/contacts/<contact-id>/
.
S3 没有目录,虽然您可以像演示的那样以伪目录方式列出文件,但本身没有目录“文件”。
您可能无意中创建了一个名为users/<user-id>/contacts/<contact-id>/
.
回答by Vic K
While everybody say that there are no directories and files in s3, but only objects (and buckets), which is absolutely true, I would suggest to take advantage of CommonPrefixes, described in thisanswer. So, you can do following to get list of "folders" (commonPrefixes) and "files" (objectSummaries):
虽然每个人都说 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());
}
In your case, for objectSummaries (files) it should return (in case of correct prefix):
users/user-id/contacts/contact-id/file1.txt
users/user-id/contacts/contact-id/file2.txt
for commonPrefixes:
users/user-id/contacts/contact-id/
在您的情况下,对于 objectSummaries(文件),它应该返回(如果前缀正确):
users/user-id/contacts/contact-id/file1.txt
users/user-id/contacts/contact-id/file2.txt
对于 commonPrefixes:
users/user-id/contacts/contact-id/
回答by Yaroslav Malyk
you can check the type. s3 has a special application/x-directory
你可以检查类型。s3 有一个特殊的application/x 目录
bucket.objects({:delimiter=>"/", :prefix=>"f1/"}).each { |obj| p obj.object.content_type }
回答by BartoszMiller
As other have already said, everything in S3 is an object. To you, it may be files and folders. But to S3, they're just objects.
正如其他人已经说过的,S3 中的一切都是一个对象。对您来说,它可能是文件和文件夹。但对 S3 来说,它们只是对象。
If you don't need objects which end with a '/' you can safely delete them e.g. via REST api or AWS Java SDK (I assume you have write access). You will not lose "nested files" (there no files, so you will not lose objects whose names are prefixed with the key you delete)
如果您不需要以“/”结尾的对象,您可以安全地删除它们,例如通过 REST api 或 AWS Java SDK(我假设您有写访问权限)。您不会丢失“嵌套文件”(没有文件,因此您不会丢失名称以您删除的键为前缀的对象)
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard().withCredentials(new ProfileCredentialsProvider()).withRegion("region").build();
amazonS3.deleteObject(new DeleteObjectRequest("my-bucket", "users/<user-id>/contacts/<contact-id>/"));
Please note that I'm using ProfileCredentialsProvider
so that my requests are not anonymous. Otherwise, you will not be able to delete an object. I have my AWS keep key stored in ~/.aws/credentials file.
请注意,我正在使用,ProfileCredentialsProvider
所以我的请求不是匿名的。否则,您将无法删除对象。我的 AWS 保留密钥存储在 ~/.aws/credentials 文件中。
回答by TuanDPH
Based on @davioooh answer. This code is worked for me.
基于@davioooh 答案。这段代码对我有用。
ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName("your-bucket")
.withPrefix("your/folder/path/").withDelimiter("/");