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

是否可暂停恢复AWS S3存储桶对象下载?aws-sdk-js是否支持该功能?

AWS S3 下载暂停/恢复功能实现方案(Electron + aws-sdk-js 环境)

原生支持情况

aws-sdk-js(v2、v3 版本均支持)原生具备实现暂停、恢复下载的能力,不需要额外引入第三方依赖,核心依赖 S3 服务本身支持的 HTTP Range 范围请求特性。

实现逻辑

原理非常简单:

  • 暂停:中断当前正在执行的下载请求,本地持久化记录当前已下载的字节偏移量、S3 对象的 ETag(用于校验对象是否变更)、本地文件路径
  • 恢复:读取本地记录的偏移量,调用 S3 接口时指定 Range 请求头,从偏移量位置开始下载剩余内容,追加写入本地文件即可

代码实现示例(aws-sdk-js v3,Electron 主进程环境可用)

1. 状态存储定义

你可以把该状态持久化到 Electron 本地存储、配置文件中,应用重启后依然可以恢复下载:

const { S3Client, HeadObjectCommand, GetObjectCommand } = require("@aws-sdk/client-s3");
const fs = require("node:fs");
const path = require("node:path");

const s3Client = new S3Client({
  region: "你的S3桶所在区域",
  // 你的AWS认证配置
});

// 下载状态,可根据实际需求持久化
const downloadState = {
  bucket: "目标桶名",
  key: "S3对象的Key",
  localSavePath: path.join(__dirname, "下载的文件保存路径"),
  downloadedBytes: 0,
  totalBytes: 0,
  eTag: "",
  isPaused: false,
  currentDownloadTask: null,
};

2. 下载/恢复逻辑

async function runDownload() {
  // 先获取对象元信息,校验对象是否变更
  const headResp = await s3Client.send(
    new HeadObjectCommand({
      Bucket: downloadState.bucket,
      Key: downloadState.key,
    })
  );

  // 如果本地已记录ETag,和最新的ETag对比,不一致说明对象已修改,需要重新下载
  if (downloadState.eTag && downloadState.eTag !== headResp.ETag) {
    downloadState.downloadedBytes = 0;
    if (fs.existsSync(downloadState.localSavePath)) {
      fs.unlinkSync(downloadState.localSavePath);
    }
  }

  downloadState.totalBytes = headResp.ContentLength;
  downloadState.eTag = headResp.ETag;

  // 读取本地已下载的文件大小
  if (fs.existsSync(downloadState.localSavePath)) {
    const fileStats = fs.statSync(downloadState.localSavePath);
    downloadState.downloadedBytes = fileStats.size;
  }

  // 已下载完成直接返回
  if (downloadState.downloadedBytes >= downloadState.totalBytes) {
    console.log("文件已下载完成");
    return;
  }

  // 构造范围下载请求
  const getObjectCmd = new GetObjectCommand({
    Bucket: downloadState.bucket,
    Key: downloadState.key,
    Range: `bytes=${downloadState.downloadedBytes}-`,
  });

  downloadState.isPaused = false;
  downloadState.currentDownloadTask = s3Client.send(getObjectCmd);
  const downloadResp = await downloadState.currentDownloadTask;

  // 追加写入本地文件
  const writeStream = fs.createWriteStream(downloadState.localSavePath, { flags: "a" });
  const reader = downloadResp.Body.getReader();

  while (true) {
    // 检测到暂停标记,终止下载流程
    if (downloadState.isPaused) {
      await reader.cancel();
      writeStream.close();
      return;
    }
    const { done, value } = await reader.read();
    if (done) break;
    writeStream.write(value);
    downloadState.downloadedBytes += value.length;
    // 这里可以自行添加下载进度回调逻辑
  }

  writeStream.close();
  console.log("文件下载完成");
}

3. 暂停逻辑

function pauseDownload() {
  downloadState.isPaused = true;
  // 也可以直接中断请求:downloadState.currentDownloadTask.abort()
}

额外优化建议

  • 对于超过10GB的大文件,建议拆分为多个10MB~100MB大小的分段并行下载,暂停时记录每个分段的下载状态,恢复时只下载未完成的分段,下载速度更快
  • Electron 渲染进程调用的话,可以通过预加载脚本把下载、暂停方法暴露给渲染层,避免把AWS认证信息暴露到渲染进程
  • 下载过程中建议定时持久化downloadState状态,避免应用异常退出导致下载进度丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:09:02