我有一些Java代码试图从S3存储桶中检索文件和文件夹列表。对于这个问题,我真正感兴趣的是文件夹。
ListObjectsRequest req = new ListObjectsRequest()
.withBucketName(bucket_name)
.withPrefix(prefix);
ObjectListing listing;
do {
listing = client.listObjects(req);
for (S3ObjectSummary summary : listing.getObjectSummaries()) {
System.out.println("key: " + summary.getKey());
}
req.setMarker(listing.getNextMarker());
} while (listing.isTruncated());
对于我在AWS Web控制台UI中手动创建的存储桶,我得到了文件和文件夹的列表:
key: foo/
key: foo/hello.txt
key: bar/
key: bar/world.txt
当我使用一个存储桶时,我使用TransferManager
和Upload
以编程方式在Java中上传所有文件,但不会返回文件夹:
key: foo/hello.txt
key: bar/world.txt
为什么存在这种差异?
在AWS Web控制台中,据我所知,这两个存储桶的外观和行为相同。当我尝试以编程方式检索密钥时,为什么它们的行为会有所不同?我读过的所有内容都暗示S3中的文件夹概念只是一种便利,我没有看到任何方式以编程方式创建我随后可以通过listObjects
检索的文件夹。
如何列出文件夹?
答案 0 :(得分:0)
S3控制台存在鸡与蛋的问题,您所看到的就是解决方法的证据。
S3中确实没有文件夹,但为方便起见,控制台根据路径中显示的/
分隔符显示层次结构中的文件夹。
但由于只有文件夹存在"因为有些物品似乎是"在"文件夹,没有显示"空的"控制台中的文件夹...以及在手动将文件上传到"之前一个文件夹,你必须选择那个文件夹,当然不存在,所以它不能被显示或选择。
当然,除非文件夹中有一个零长度名称的空文件。
再次重读,因为我没有充分利用它。
这基本上就是你所看到的。在控制台中创建一个名为foo
的文件夹,您的存储桶中将有一个名为foo/
的空对象。如果你以正确的方式思考它,那就是一个名为"" (空字符串)在名为foo
的文件夹中,带有分隔符/
。显然,文件不能有""作为一个名字,所以来自"内部"文件夹,文件不存在,但来自"外部"文件夹,它足以使文件夹显示在控制台中,即使是空的。
此对象没有明显的目的,除了导致foo
文件夹出现在控制台中,即使/当桶中没有前缀为foo/
的文件时,可能是为了简化对于那些认为S3是传统分层的人而言,这种转变。
答案 1 :(得分:0)
您可以使用minio-java库实现此目的:
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.errors.ClientException;
import io.minio.messages.Item;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Iterator;
public class ListObjects {
public static void main(String[] args) throws IOException, XmlPullParserException, ClientException {
System.out.println("ListObjects app");
// Set s3 endpoint, region is calculated automatically
MinioClient s3Client = new MinioClient("https://s3.amazonaws.com", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY");
String bucket = "mybucket"
String prefix = ""
boolean recursive = false
// list objects
Iterator<Result<Item>> myObjects = s3Client.listObjects(bucket, prefix, recursive);
while (myObjects.hasNext()) {
Result<Item> result = myObjects.next();
Item object = result.getResult();
System.out.println(object);
}
}
}
前缀为""
,递归为false
,它将打印存储桶中的顶级文件夹