You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot下用AWS Java SDK S3直接上传数据至S3桶(无需本地文件)

直接上传数据到AWS S3无需本地文件副本

问题分析

你的现有代码通过本地文件中转数据,在处理数百万文件场景下会带来存储压力和IO性能损耗。AWS SDK for Java提供了直接上传数据流的API,完全可以避免本地文件生成,同时你需要修正List<Map<String,Object>>转字节数组的错误方式(不能直接调用getBytes(),需先序列化为JSON)。

解决方案代码

利用Spring Boot自带的Jackson ObjectMapper序列化数据,结合ByteArrayInputStream直接上传至S3:

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class S3Uploader {
    private static final Logger log = LoggerFactory.getLogger(S3Uploader.class);
    private final AmazonS3 s3Client;
    private final ObjectMapper objectMapper;

    // 通过构造函数注入Spring管理的S3客户端和ObjectMapper
    public S3Uploader(AmazonS3 s3Client, ObjectMapper objectMapper) {
        this.s3Client = s3Client;
        this.objectMapper = objectMapper;
    }

    public void uploadToS3(String fileName, String folderName, List<Map<String, Object>> dataList) {
        String bucketName = "myBucketName";
        // 拼接S3中的对象键(模拟文件夹结构)
        String s3ObjectKey = folderName + "/" + fileName;

        try {
            // 1. 将结构化数据序列化为JSON字节数组
            byte[] jsonDataBytes = objectMapper.writeValueAsBytes(dataList);
            // 2. 将字节数组包装为输入流
            ByteArrayInputStream inputStream = new ByteArrayInputStream(jsonDataBytes);

            // 3. 设置S3对象元数据(指定内容类型、长度等)
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(jsonDataBytes.length);
            metadata.setContentType("application/json");

            // 4. 直接上传数据流到S3,无需本地文件
            s3Client.putObject(new PutObjectRequest(bucketName, s3ObjectKey, inputStream, metadata));
        } catch (IOException e) {
            log.error("上传数据至S3失败: {}", e.getMessage(), e);
        }
    }
}

关键说明

  1. JSON序列化:使用ObjectMapper将List<Map>转为标准JSON字节数组,这是处理结构化数据的正确方式,避免了原代码中getBytes()的错误调用。
  2. 无文件中转:通过ByteArrayInputStream将内存中的字节数据直接传入S3 API,完全跳过本地文件IO操作。
  3. 元数据设置:通过ObjectMetadata指定Content-Type为application/json,让S3和下游服务正确识别文件类型;同时设置ContentLength可以提升上传效率。
  4. 异常处理:完善了日志输出,同时无需手动关闭ByteArrayInputStream(其关闭操作无实际IO影响)。

大文件场景扩展

如果单条数据量过大(超过内存承载能力),可以使用AWS SDK的分段上传功能,结合TransferManager实现流式上传,避免内存溢出:

// 示例:使用TransferManager上传大数据流
TransferManager transferManager = TransferManagerBuilder.standard()
        .withS3Client(s3Client)
        .build();
Upload upload = transferManager.upload(bucketName, s3ObjectKey, inputStream, metadata);
upload.waitForCompletion();

内容的提问来源于stack exchange,提问作者vyas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:17:37