Node.js如何直接将大数据流上传到AWS S3而无需先本地存储?
Node.js 流式上传大体积数据到 AWS S3(无需本地暂存)
完全可以实现无本地文件暂存的流式上传,AWS 官方 SDK 原生支持对接 Node.js Stream 接口,结合 S3 分片上传能力,可以做到边生成/接收/处理数据边上传,内存仅需要存放当前正在上传的分片数据,适配TB级大文件的上传场景。
前置依赖
推荐使用 AWS SDK v3,按需安装所需模块:npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
核心实现示例
1. 初始化S3客户端
const { S3Client } = require('@aws-sdk/client-s3'); const { Upload } = require('@aws-sdk/lib-storage'); const s3Client = new S3Client({ region: '替换为你的AWS区域,例如ap-northeast-1', credentials: { accessKeyId: '替换为你的AccessKeyId', secretAccessKey: '替换为你的SecretAccessKey' } });
2. 封装流式上传方法
直接将可读流作为上传参数传入,不需要转换为完整Buffer或本地文件路径:
async function uploadStreamToS3(readableStream, bucket, s3Key) { const uploader = new Upload({ client: s3Client, params: { Bucket: bucket, Key: s3Key, Body: readableStream }, // 可选配置,根据实际场景调整 partSize: 10 * 1024 * 1024, // 单分片大小,单位字节,最小5MB,此处设为10MB queueSize: 4, // 并发上传的分片数 leavePartsOnError: false // 上传失败时自动清理已上传的分片 }); // 可选:监听上传进度 uploader.on('httpUploadProgress', (progress) => { console.log(`上传进度:${((progress.loaded / progress.total) * 100).toFixed(2)}%`); }); return await uploader.done(); }
3. 常见使用场景示例
场景1:直接转存上游HTTP响应流到S3
无需把上游返回的大文件下载到本地:
const axios = require('axios'); // 注意要指定responseType为stream,拿到响应的可读流 const res = await axios.get('上游大资源地址', { responseType: 'stream' }); await uploadStreamToS3(res.data, '你的桶名', 'S3上的存储路径/文件名');
场景2:上传自定义生成的数据流
比如你需要动态生成大CSV/JSON文件,直接把生成流上传:
const { Readable } = require('stream'); // 自定义可读流,模拟动态生成大量数据的逻辑 const customStream = new Readable({ read(size) { // 这里写你生成数据的逻辑,边生成边push到流里 // 数据生成完成后push(null)结束流 } }); await uploadStreamToS3(customStream, '你的桶名', 'S3上的存储路径/文件名');
注意事项
- S3 分片上传要求除最后一个分片外,每个分片最小为5MB,调整
partSize时不要低于这个阈值 - 建议配置S3桶的生命周期规则,自动清理超过7天的未完成分片上传任务,避免产生不必要的存储费用
- 如果你仍在使用AWS SDK v2,对应使用
s3.upload()方法,同样支持直接传入可读流作为Body参数,使用逻辑基本一致
内容的提问来源于stack exchange,提问作者Ninja
相关产品推荐
相关产品推荐

