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

在AWS SDK v3中如何通过UploadId跟踪S3分片上传进度?

AWS SDK v3 中 UploadPart 跟踪分片上传进度的等效实现

在AWS SDK v3中,UploadPartCommand本身没有提供像v2那样直接的httpUploadProgress事件监听,需要通过包装Body流的方式来实现分片上传进度的跟踪,同时可以关联对应的UploadId和PartNumber。

实现步骤与代码示例

  1. 首先确保安装了必要的依赖:
npm install @aws-sdk/client-s3 @aws-sdk/util-stream-node
  1. 自定义进度跟踪流,并包装分片上传的Body:
const { S3Client, UploadPartCommand } = require("@aws-sdk/client-s3");
const { createReadStream } = require("@aws-sdk/util-stream-node");
const { Transform } = require("stream");

// 自定义Transform流,用于跟踪上传进度
class ProgressTracker extends Transform {
  constructor(options = {}) {
    super(options);
    this.totalBytes = options.totalBytes || 0;
    this.uploadedBytes = 0;
    this.onProgress = options.onProgress || (() => {});
  }

  _transform(chunk, encoding, callback) {
    this.uploadedBytes += chunk.length;
    // 触发进度回调,携带分片编号和上传ID
    this.onProgress({
      loaded: this.uploadedBytes,
      total: this.totalBytes,
      partNumber: this.partNumber,
      uploadId: this.uploadId
    });
    this.push(chunk);
    callback();
  }
}

// 初始化S3客户端
const s3Client = new S3Client({
  // 你的AWS配置,比如region、credentials等
});

// 封装带进度跟踪的分片上传方法
async function uploadPartWithProgress(uploadParams) {
  // 创建进度跟踪器
  const progressTracker = new ProgressTracker({
    totalBytes: uploadParams.ContentLength,
    onProgress: (evt) => {
      console.log(`分片 ${evt.partNumber} (UploadId: ${evt.uploadId}) 上传进度: ${((evt.loaded / evt.total) * 100).toFixed(2)}%`);
      console.log(`已上传: ${evt.loaded} / ${evt.total} 字节`);
    }
  });

  // 绑定当前分片的标识信息
  progressTracker.partNumber = uploadParams.PartNumber;
  progressTracker.uploadId = uploadParams.UploadId;

  // 将原始Body转换为带进度跟踪的流
  const trackedBody = typeof uploadParams.Body === 'string'
    ? createReadStream(uploadParams.Body).pipe(progressTracker)
    : uploadParams.Body.pipe(progressTracker);

  // 替换参数中的Body为跟踪流
  const paramsWithProgress = {
    ...uploadParams,
    Body: trackedBody
  };

  // 执行分片上传并返回结果
  return await s3Client.send(new UploadPartCommand(paramsWithProgress));
}

// 使用示例
(async () => {
  try {
    const partInfo = await uploadPartWithProgress({
      Bucket: "BucketName",
      Key: "目标对象Key",
      UploadId: "你的多部分上传ID",
      PartNumber: 1, // 当前分片编号(1-10000)
      ContentLength: 1048576, // 分片大小(示例为1MB)
      Body: "/本地分片文件路径" // 或直接传入Readable流
    });
    console.log("分片上传完成,ETag:", partInfo.ETag);
  } catch (err) {
    console.error("分片上传失败:", err);
  }
})();

补充说明

  • 如果使用全局中间件监听进度(如NodeHttpHandler的progress配置),无法直接关联到特定的UploadId和PartNumber,因此在多分片并行上传场景下,自定义流的方式更精准。
  • 上述代码中的ProgressTracker可以根据需求扩展,比如添加速度计算、状态标记等功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:55:04