【问题标题】:AWS Java SDK v2: Upload a directory to S3AWS Java SDK v2:将目录上传到 S3
【发布时间】:2021-10-27 10:08:43
【问题描述】:

我想使用 AWS Java SDK v2 将目录上传到 S3。

例如,我将如何实现以下功能?

fun uploadDirectory(bucket: String, prefix: String, directory: Path)

我希望在 S3 上将 directory 的内容复制到 s3://bucket/prefix/

v2 SDK 文档有一个uploading a single object 的示例,但似乎没有与 v1 中的这个 Upload a Directory 示例等效的示例。

【问题讨论】:

    标签: kotlin amazon-s3 file-upload aws-java-sdk-2.x directory-upload


    【解决方案1】:

    您可以使用以下策略来实现它:

    1. 使用Files.walk 遍历目录,识别所有文件。
    2. 使用 SDK 异步上传文件,通过 S3AsyncClient.putObject
    3. 使用CompletableFuture.allOf合并所有上传任务,等待完成。

    此策略使用异步客户端的default thread pool 50 个线程。对于包含数千个文件的目录,这对我来说效果很好。

    这里的s3Prefix是添加到每个上传到bucket的object的前缀,相当于目标目录。

    fun uploadDirectory(s3Bucket: String, s3Prefix: String, directory: Path) {
        require(directory.isDirectory())
    
        Files.walk(directory).use { stream ->
            stream.asSequence()
                .filter { it.isRegularFile() }
                .map { path ->
                    putObject(
                        s3Bucket = s3Bucket,
                        s3Key = "$s3Prefix/${directory.relativize(path)}",
                        path = path
                    )
                }
                .toList().toTypedArray()
        }.let { CompletableFuture.allOf(*it) }.join()
    }
    
    private fun putObject(s3Bucket: String, s3Key: String, path: Path)
        : CompletableFuture<PutObjectResponse> {
        val request = PutObjectRequest.builder()
            .bucket(s3Bucket)
            .key(s3Key)
            .build()
    
        return s3AsyncClient.putObject(request, path)
    }
    

    【讨论】:

      【解决方案2】:

      TransferManager 以及其他一些高级库在 v2 中尚不可用。所以你必须改用 v1,来自migration guide

      高级库,例如 Amazon S3 Transfer Manager 和 Amazon SQS 客户端缓冲,尚未在版本中提供 2.x。有关库的完整列表,请参阅 AWS SDK for Java 2.x 更改日志。

      如果您的应用程序依赖于这些库,请参阅同时使用这两个 SDK 并排学习如何配置您的 pom.xml 以同时使用 1.x 和 2.x。请参阅适用于 Java 的 AWS 开发工具包 2.x 更改日志以了解有关更新 这些库。

      【讨论】:

      • 有一个preview的传输管理器可用,但还不支持上传目录。但是,可以在没有传输管理器的情况下使用异步上传来做到这一点,请参阅我的回答。
      • @AdamMillerchip 当然可以遍历目录并单独放置对象,但您问的是类似于TransferManager 的解决方案,正如我所说的,它尚不可用。
      • 我问了如何使用AWS SDK v2编写一个将目录上传到S3的函数,我没有问具体的方法。
      • 好的,所以您知道如何使用 s3 v2 上传单个对象,但您不知道如何遍历目录。如果是这样,那么您肯定已经了解了有关 java sdk 的新知识。我为你感到高兴
      猜你喜欢
      • 2015-04-18
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多