通过 Java SDK 和 AWS 控制台上传时的不同 S3 对象列表

Different S3 object listing when uploading via Java SDK and AWS Console

我在 S3 中有一个具有以下结构和内容的存储桶:

javaFolderA/
└── javaFolderB/
    └── javaFile.tmp
consoleFolderA/
└── consoleFolderB/
    └── consoleFile.tmp

java* 文件夹和文件是通过 Java SDK 上传的:

final File file = new File("C:\javaFolderA\javaFolderB\javaFile.tmp");
client.putObject("testbucket", "javaFolderA/javaFolderB/javaFile.tmp", file);

console* 个文件夹和文件来自 Web 控制台 created/uploaded(单击每个文件夹的“+ 创建文件夹”按钮,然后使用 public 读取权限上传文件) .

在 Web 控制台中,单击创建新存储桶后,显示以下消息:

When you create a folder, S3 console creates an object with the above name appended by suffix "/" and that object is displayed as a folder in the S3 console.

因此,正如预期的那样,使用上面的文件夹和文件,我们使用以下键在存储桶中创建了 3 个对象:

SDK 上传的结果是带有键的单个对象:javaFolderA/javaFolderB/javaFile.tmp。这是有道理的,因为我们只放置一个对象,而不是三个。但是,这会导致在列出存储桶的内容时出现不一致。即使每个目录中只有一个实际文件,列出控制台场景的内容 returns 多个。

我的问题是为什么会这样我怎样才能实现一致的行为?似乎没有办法通过 SDK "upload a directory"(在引号中,因为我知道实际上 folders/directories)。

我可以从 CLI 验证对象的数量及其密钥:

C:\Users\avojak>aws s3api list-objects --bucket testbucket
{
    "Contents": [
        {
            "LastModified": "2018-01-02T22:43:55.000Z",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "StorageClass": "STANDARD",
            "Key": "consoleFolderA/",
            "Owner": {
                "DisplayName": "foo.bar",
                "ID": "2c401638471162eda7a3b48e41dfb9261d9022b56ce6b00c0ecf544b3e99ca93"
            },
            "Size": 0
        },
        {
            "LastModified": "2018-01-02T22:44:02.000Z",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "StorageClass": "STANDARD",
            "Key": "consoleFolderA/consoleFolderB/",
            "Owner": {
                "DisplayName": "foo.bar",
                "ID": "2c401638471162eda7a3b48e41dfb9261d9022b56ce6b00c0ecf544b3e99ca93"
            },
            "Size": 0
        },
        {
            "LastModified": "2018-01-02T22:44:16.000Z",
            "ETag": "\"968fe74fc49094990b0b5c42fc94de19\"",
            "StorageClass": "STANDARD",
            "Key": "consoleFolderA/consoleFolderB/consoleFile.tmp",
            "Owner": {
                "DisplayName": "foo.bar",
                "ID": "2c401638471162eda7a3b48e41dfb9261d9022b56ce6b00c0ecf544b3e99ca93"
            },
            "Size": 69014
        },
        {
            "LastModified": "2018-01-02T22:53:13.000Z",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "StorageClass": "STANDARD",
            "Key": "javaFolderA/javaFolderB/javaFile.tmp",
            "Owner": {
                "DisplayName": "foo.bar",
                "ID": "2c401638471162eda7a3b48e41dfb9261d9022b56ce6b00c0ecf544b3e99ca93"
            },
            "Size": 0
        }
    ]
}

如果您更喜欢控制台实现,那么您需要模拟它。这意味着您的 SDK 客户端需要在必要时创建中间体 'folders'。您可以通过创建其键以正斜杠结尾(如果这是您的 'folder' 分隔符)的零大小对象来实现。

AWS 控制台以这种方式运行,允许您创建 'folders',因为许多 AWS 控制台用户更喜欢文件夹和文件的概念,而不是对象(和键)。

但是,在我看来,很少需要这样做。您的 SDK 客户端应该被实施以处理这些 'folders' 的存在和不存在。更多信息 here.