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

如何最小化修改代码适配未知长度Stream的S3上传?

问题:S3上传未知长度Stream报错,如何最小改动适配?

我现有代码在普通文件上传时运行正常,但使用未知长度的Stream上传时触发以下报错:

Are you using a Stream of unknown length as the Body of a PutObject request? Consider using Upload instead from @aws-sdk/lib-storage.

尝试过多种方式使用lib-storage但未能成功实现需求,想知道对现有代码做最小改动就能支持未知长度Stream的方法。

现有代码:

import { S3Client, HeadObjectCommand, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'

// ...

const s3 = new S3Client({
  region: 'ap-southeast-2',
  defaultProvider
})

// ...

class Files extends AuditMixin {
  async _uploadToAmazon (path, body) {
    const params = {
      Bucket: vars.config.amazonBucket,
      Key: path
    }

    let found = 0
    try {
      await s3.send(new HeadObjectCommand(params))
      found = 1
    } catch (e) {
      if (e.name === 'NotFound') found = 0
    }

    if (found) {
      console.log('****************Skipped! ', path)
      return { key: path }
    } else {
      console.log('I would upload', path)
      try {
        const response = await s3.send(new PutObjectCommand({ ...params, Body: body }))
        return response
      } catch (error) {
        console.error('Error uploading to Amazon S3:', error)
        throw error
      }
    }
  }
}

目前有一个可行但体验很差的临时方案:

import cs from 'convert-stream'
// ...

if (typeof body.pipe === 'function') {
  body = await cs.toBuffer(body)
}
const response = await s3.send(new PutObjectCommand({ ...params, Body: body }))

解决方案:用@aws-sdk/lib-storage的Upload替换PutObjectCommand

只需两步最小改动,无需转换整个Stream为Buffer:

  1. 导入Upload类:
// 在原有导入基础上添加这行
import { Upload } from "@aws-sdk/lib-storage";
  1. 修改_uploadToAmazon方法中上传逻辑的代码块,替换原有的PutObjectCommand调用:
// 替换else分支里的try代码块
try {
  console.log('I would upload', path)
  // 用Upload替代PutObjectCommand
  const upload = new Upload({
    client: s3,
    params: { ...params, Body: body }
  });
  const response = await upload.done();
  return response;
} catch (error) {
  console.error('Error uploading to Amazon S3:', error)
  throw error
}

说明

  • 原有文件存在检查逻辑完全保留,无需修改
  • Upload会自动处理未知长度的Stream,采用分块上传机制,避免了把整个Stream加载到内存的问题
  • 接口返回值与原PutObjectCommand的返回兼容,无需调整后续逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:41:26