AWS S3中“文件夹”的检索不一致,具体取决于存储桶的填充方式

时间:2015-11-19 07:38:33

标签: java amazon-s3

我有一些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

当我使用一个存储桶时,我使用TransferManagerUpload以编程方式在Java中上传所有文件,但不会返回文件夹:

key: foo/hello.txt
key: bar/world.txt

为什么存在这种差异?

在AWS Web控制台中,据我所知,这两个存储桶的外观和行为相同。当我尝试以编程方式检索密钥时,为什么它们的行为会有所不同?我读过的所有内容都暗示S3中的文件夹概念只是一种便利,我没有看到任何方式以编程方式创建我随后可以通过listObjects检索的文件夹。

如何列出文件夹?

2 个答案:

答案 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,它将打印存储桶中的顶级文件夹