首页 > 解决方案 > 使用高级多部分上传仍然没有指定内容长度的警告

问题描述

即使我使用的是高级多部分,我仍然在控制台中收到警告:

WARN - com.amazonaws.services.s3.AmazonS3Client - No content length specified for stream data.  Stream contents will be buffered in memory and could result in out of memory errors.

这就是我使用高级分段上传的方式,就像这里一样:https ://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-upload-object.html

      val tm: TransferManager = TransferManagerBuilder
        .standard()
        .withS3Client(s3Client)
        .withMultipartUploadThreshold(5248000)
        .build();

      val metadata = new ObjectMetadata()
      metadata.setContentType(mimeType)
      val request = new PutObjectRequest(bucketName, key, inputStream, metadata)

      val upload = tm.upload(request)
      upload.waitForCompletion()

5248000 是 5MB,我尝试上传比这大得多的文件,因此它应该使用多部分策略,如withMultipartUploadThreshold文档中所述:

设置何时使用分段上传的大小阈值(以字节为单位)。超过此大小的上传将自动使用分段上传策略,而小于此阈值的上传将使用单个连接上传整个对象。

为什么它仍然给出这个警告?

标签: amazon-web-servicesamazon-s3aws-sdk-java

解决方案


AWS SDK for Java的文档在 ObjectMetadata 上提到了这一点:

将对象上传到 S3 时需要此字段,但 Amazon Web Services S3 Java 客户端会在直接处理文件时自动设置它。直接从流上传时,如果可能,请设置此字段。否则,客户端必须缓冲整个流,以便在将数据发送到 Amazon S3 之前计算内容长度。

换句话说,您需要在构造对象metadata.setContentLength(x)之前显式调用文件或流大小。PutObjectRequest如果您不这样做,AWS 开发工具包将需要在 ram 中缓冲整个流,这可能会耗尽较大对象的内存,这会触发您看到的警告。


推荐阅读