如何使用S3TransferManager批量上传内存文件无需物理存储
批量上传内存文件到S3(无需磁盘存储)
S3 Transfer Manager的uploadDirectory方法仅适用于磁盘目录下的物理文件,无法直接处理内存中的文件列表。要实现批量上传内存数据,你需要为每个内存条目单独创建上传任务,再批量等待所有任务完成,具体方案如下:
核心实现思路
- 为每个内存中的文件数据生成独立的
PutObjectRequest(每个文件对应唯一的S3 Key) - 用
RequestBody直接包装内存数据(字节数组、输入流等),无需写入磁盘 - 收集所有上传任务的
CompletableFuture,通过CompletableFuture.allOf等待全部上传完成
Kotlin代码示例
假设你有一个内存文件列表,每个条目包含S3存储键、文件内容字节数组和内容类型:
import software.amazon.awssdk.services.s3.model.PutObjectRequest import software.amazon.awssdk.transfer.s3.S3TransferManager import software.amazon.awssdk.core.sync.RequestBody import java.util.concurrent.CompletableFuture // 定义内存文件的数据结构 data class InMemoryFile( val s3Key: String, val content: ByteArray, val contentType: String = "application/json; charset=UTF-8" ) fun main() { val bucketName = "your-target-bucket" val transferManager = S3TransferManager.create() // 模拟你的内存文件列表 val memoryFiles = mutableListOf( InMemoryFile("docs/file1.json", "{\"id\": 1, \"name\": \"test1\"}".toByteArray()), InMemoryFile("docs/file2.json", "{\"id\": 2, \"name\": \"test2\"}".toByteArray()) ) // 生成所有上传任务的Future集合 val uploadFutures = memoryFiles.map { file -> val putRequest = PutObjectRequest.builder() .bucket(bucketName) .key(file.s3Key) .contentType(file.contentType) .build() // 直接从内存字节创建上传任务,无需磁盘文件 val upload = transferManager.uploadFile { builder -> builder.putObjectRequest(putRequest) .source(RequestBody.fromBytes(file.content)) } upload.completionFuture() } // 等待所有上传任务完成 CompletableFuture.allOf(*uploadFutures.toTypedArray()).join() // 可选:遍历结果,处理单个任务的成功/失败 uploadFutures.forEachIndexed { index, future -> runCatching { future.join() } .onSuccess { println("文件${memoryFiles[index].s3Key}上传成功") } .onFailure { println("文件${memoryFiles[index].s3Key}上传失败:${it.message}") } } transferManager.close() }
关键说明
- 避免磁盘写入:使用
RequestBody.fromBytes/fromInputStream/fromString等方法直接将内存数据传递给S3,完全跳过磁盘存储步骤 - 独立请求配置:每个文件必须单独创建
PutObjectRequest,因为每个文件的S3 Key是唯一的,无法复用同一个请求模板 - 批量等待:
CompletableFuture.allOf会等待所有上传任务完成,适合批量场景;如果需要并行度控制,可以结合线程池调整(TransferManager默认会管理线程池)
内容的提问来源于stack exchange,提问作者wmrodrigues
相关产品推荐
相关产品推荐

