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

如何将文件夹中所有文件上传至AWS S3存储桶?

实现本地文件夹批量上传至AWS S3存储桶

要实现指定文件夹路径后上传所有文件,核心是遍历文件夹内的所有文件,再逐个执行S3上传操作。以下是修改后的完整代码,包含基础批量上传和递归上传子文件夹两种方案:

方案1:仅上传目标文件夹下的一级文件

const AWS = require('aws-sdk');
const fs = require('fs').promises;
const path = require('path');
const { createReadStream } = require('fs');

async function uploadFolderToS3(localFolderPath, s3BucketName, s3Prefix = 'folder/') {
  try {
    const s3 = new AWS.S3();
    // 读取文件夹内所有条目
    const files = await fs.readdir(localFolderPath);

    // 遍历条目,仅上传文件(跳过子文件夹)
    const uploadPromises = files.map(async (fileName) => {
      const localFilePath = path.join(localFolderPath, fileName);
      const stats = await fs.stat(localFilePath);
      if (!stats.isFile()) return;

      // 生成S3对象键,添加时间戳避免重名
      const s3Key = `${s3Prefix}${Date.now()}_${fileName}`;
      const params = {
        Bucket: s3BucketName,
        Key: s3Key,
        Body: createReadStream(localFilePath),
      };

      const uploadResult = await s3.upload(params).promise();
      console.log(`上传成功: ${uploadResult.Location}`);
      return uploadResult;
    });

    // 等待所有上传完成,过滤无效结果
    const successfulUploads = (await Promise.all(uploadPromises)).filter(Boolean);
    console.log(`全部上传完成,成功上传 ${successfulUploads.length} 个文件`);
    return successfulUploads;
  } catch (error) {
    console.error('上传出错:', error);
    throw error;
  }
}

// 调用示例:替换为你的存储桶名称
uploadFolderToS3('./data', '你的存储桶名称')
  .catch(err => console.error(err));

方案2:递归上传所有子文件夹及文件

如果需要包含子文件夹的内容,可添加递归逻辑:

const AWS = require('aws-sdk');
const fs = require('fs').promises;
const path = require('path');
const { createReadStream } = require('fs');

async function uploadFolderToS3(localFolderPath, s3BucketName, s3Prefix = 'folder/') {
  try {
    const s3 = new AWS.S3();
    const files = await fs.readdir(localFolderPath);
    const uploadPromises = [];

    for (const fileName of files) {
      const localFilePath = path.join(localFolderPath, fileName);
      const stats = await fs.stat(localFilePath);

      if (stats.isDirectory()) {
        // 递归上传子文件夹,更新S3前缀以保持目录结构
        const subFolderPrefix = `${s3Prefix}${fileName}/`;
        uploadPromises.push(uploadFolderToS3(localFilePath, s3BucketName, subFolderPrefix));
      } else {
        const s3Key = `${s3Prefix}${Date.now()}_${fileName}`;
        const params = {
          Bucket: s3BucketName,
          Key: s3Key,
          Body: createReadStream(localFilePath),
        };
        const uploadResult = await s3.upload(params).promise();
        console.log(`上传成功: ${uploadResult.Location}`);
        uploadPromises.push(uploadResult);
      }
    }

    // 扁平化递归返回的结果,过滤无效项
    const successfulUploads = (await Promise.all(uploadPromises)).flat().filter(Boolean);
    console.log(`全部上传完成,成功上传 ${successfulUploads.length} 个文件`);
    return successfulUploads;
  } catch (error) {
    console.error('上传出错:', error);
    throw error;
  }
}

// 调用示例
uploadFolderToS3('./data', '你的存储桶名称')
  .catch(err => console.error(err));

关键说明

  • 使用fs.promises异步API替代回调,代码更简洁易维护
  • 通过fs.stat判断条目类型,区分文件和文件夹
  • 用Promise.all批量处理上传请求,提升效率
  • S3对象键添加时间戳前缀,避免同名文件覆盖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:05:23