29

我对AWS Java SDK比较熟悉,也尝试过浏览对应的Javadoc,但是不知道如何创建子目录,即bucket内的目录对象,以及如何上传文件。

假设bucketNamedirName对应已经存在的bucket(具有公共权限)和一个需要在bucket中创建的新(对象)目录(即bucketName/dirName/)

我尝试了以下方法:

AmazonS3Client s3 = new AmazonS3Client(
    new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
s3.createBucket(bucketName + "/" + dirName); //throws exception

在第二行引发异常。

一个创建子目录并将文件上传到它的简短片段将不胜感激。

4

6 回答 6

51

S3 中没有“子目录”。有桶,桶内有键。

您可以使用前缀搜索来模拟传统目录。例如,您可以将以下密钥存储在存储桶中:

foo/bar1
foo/bar2
foo/bar3
blah/baz1
blah/baz2

然后做一个前缀搜索foo/,你会得到:

foo/bar1
foo/bar2
foo/bar3

有关AmazonS3.listObjects更多详细信息,请参阅。


更新:假设您已经有一个现有的存储桶,该存储桶下的键将包含/

s3.putObject("someBucket", "foo/bar1", file1);
s3.putObject("someBucket", "foo/bar2", file2);
...

然后您可以列出所有以 开头的键foo/

ObjectListing listing = s3.listObjects("someBucket", "foo/");
于 2012-07-15T11:19:47.390 回答
32

S3 看不到我们在操作系统上执行此操作的传统方式的目录。以下是创建目录的方法:

public static void createFolder(String bucketName, String folderName, AmazonS3 client) {
    // create meta-data for your folder and set content-length to 0
    ObjectMetadata metadata = new ObjectMetadata();
    metadata.setContentLength(0);

    // create empty content
    InputStream emptyContent = new ByteArrayInputStream(new byte[0]);

    // create a PutObjectRequest passing the folder name suffixed by /
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
                folderName + SUFFIX, emptyContent, metadata);

    // send request to S3 to create folder
    client.putObject(putObjectRequest);
}

正如 casablanca 已经说过的,您可以将文件上传到这样的目录:

s3.putObject("someBucket", "foo/bar1", file1);

在此处阅读整个教程以获取详细信息,最重要的是您将找到如何删除目录的信息。

于 2014-10-17T09:33:55.883 回答
3

在较新版本的 SDK 中,您可以执行以下操作(无需创建空 InputStream)来创建一个空文件夹:

String key = parentKey + newFolderName;
if (!StringUtils.endsWith(key, "/")) {
    key += "/";
}

PutObjectRequest putRequest = PutObjectRequest.builder()
        .bucket(parent.getBucket())
        .key(key)
        .acl("public-read")
        .build();
s3Client.putObject(putRequest, RequestBody.empty());
于 2019-12-26T14:51:58.310 回答
0

在这里留下这个答案,以防有人偶然发现。我一直在使用aws sdk 版本 - 1.11.875,以下在尝试将文件上传到 S3 存储桶时成功为我创建了一个文件夹。我不必像前面的答案中提到的那样显式创建文件夹。

private void uploadFileToS3Bucket(final String bucketName, final File file) {
    final String fileName = "parent/child/" + file.getName();
    final PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, file);
    amazonS3.putObject(putObjectRequest);
}

这将在指定的 S3 存储桶中创建父文件夹和父/子文件夹,并将文件上传到子文件夹。

于 2020-12-23T00:21:09.087 回答
0

这对我有用。我使用了spring boot和根据Multipart机制上传的文件。我想将我的图像保存在我的 aws s3 存储桶中的照片文件夹中。我需要像这样保存照片/mypic.jpg

----控制器类方法----

@PostMapping("/uploadFile")
    public String uploadFile(@RequestPart(value = "file") MultipartFile file) throws IOException {
        return this.amazonClient.uploadFile(file);
}

----服务类(控制器的实现)----

 public String uploadFile(MultipartFile multipartFile) throws IOException {
    
            try {
                File file = convertMultiPartToFile(multipartFile);
                String fileName = "photoes/"+generateFileName(multipartFile);  //here give any folder name you want
                uploadFileTos3bucket(fileName, file);
            } catch (AmazonServiceException ase) {
                logger.info("Caught an AmazonServiceException from GET requests, rejected reasons:");
            }
            return fileName;
        }

重点是将您想要的文件夹名称连接为文件名的前缀

另外,我将向您展示如何删除文件夹。关键是将文件夹名称作为keyName(键名称是s3存储桶中上传的对象名称。)。我也会展示代码片段。

----控制器类方法----

@DeleteMapping("/deleteFile")
    public String deleteFile(@RequestPart(value = "keyName") String keyName) {
        return this.amazonClient.deleteFile(keyName);
    }

----服务类(控制器的实现)----

 public String deleteFile(String keyName){
        try {
            s3client.deleteObject(new DeleteObjectRequest(bucketName, keyName));
        } catch (SdkClientException e) {
            e.printStackTrace();
        }
        return "deleted file successfully!";
    }

要删除我们创建的照片文件夹,请像这样调用方法。deleteFile("photos/") 重要:- / 是强制性的

于 2021-01-17T11:18:38.233 回答
-1

如果要创建文件夹,则需要使用 put 命令使用以下键在其中创建文件夹 1 :

在存储桶的根目录 -> folder1/folder1_$folder$

在路径 folder2/folder3/ -> folder2/folder3/folder1/folder1_$folder$

它始终是 all_previous_folders/folderName/folderName_$folder$

于 2017-05-26T11:22:47.360 回答