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

Java上传对象到S3桶报无内容长度警告且代码中断该如何解决

问题原因

该警告及OOM崩溃的核心原因是:使用InputStream作为S3上传源时,你没有向ObjectMetadata实例声明流的总字节长度,AWS S3 SDK只能将整个流的全部内容缓冲到内存中自行计算长度,MB级及更大的文件很容易超出JVM堆内存上限,最终导致进程异常终止。
如果使用临时文件+分片上传的方案仍然失败,通常是因为分片上传逻辑中也没有正确传入对应分片/文件的长度参数,SDK仍然触发了内存缓冲逻辑。

修复方案

方案1:补充ContentLength配置(适配现有单文件上传逻辑)

在当前代码的metadata配置步骤中,追加上传内容的长度配置即可,修改后代码如下:

InputStream inputStream = part.getInputStream();
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
        .withRegion("eu-central-1")
        .build();
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(part.getContentType());
// 新增行:传入上传内容的总字节长度,若part为ServletPart实例可直接调用getSize()获取
metadata.setContentLength(part.getSize());
logger.log("setting metadata");

PutObjectRequest request = new PutObjectRequest(bucket, fileName, inputStream, metadata);
s3Client.putObject(request);
logger.log("putting in S3 bucket");

如果你的part实例没有直接获取大小的方法,也可以先将流转换为字节数组后读取长度,单文件≤100MB时该方案更稳妥:

byte[] fileBytes = org.apache.commons.io.IOUtils.toByteArray(inputStream);
metadata.setContentLength(fileBytes.length);
// 原流已被读取完毕,需重新构造输入流传入请求
PutObjectRequest request = new PutObjectRequest(bucket, fileName, new ByteArrayInputStream(fileBytes), metadata);

方案2:使用File作为上传入参(无需手动设置长度)

如果已经将上传内容保存为本地临时文件,可直接将File实例传入PutObjectRequest,SDK会自动读取文件长度,无需手动配置ContentLength:

// tempFile为你保存的本地临时文件对象
PutObjectRequest request = new PutObjectRequest(bucket, fileName, tempFile);
s3Client.putObject(request);
  • 注意:单文件超过100MB时优先使用分片上传,降低单次上传失败的重传成本,分片大小建议设置在5MB~100MB区间,每个分片上传时也需要对应传入分片的字节长度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:36:02