如何用Node.js在两个S3存储桶间复制对象及获取全量对象
问题描述
需要将文本和媒体文件从一个S3存储桶复制到另一个存储桶,两个存储桶名称不同但可使用同一凭证访问,如何通过Node.js实现该需求?
目前已能获取对象列表,但仅返回前100个对象,同时提示还有900个以上对象,而实际存储桶内的对象总数远大于该数值。当前代码如下:
index.js
require("dotenv").config(); const AWS = require('aws-sdk'); let s3 = new AWS.S3({ secretAccessKey: process.env.SECRET_ACCESS_KEY, accessKeyId: process.env.ACCESS_KEY_ID, region: process.env.REGION }); const BUCKET = process.env.BUCKET_NAME; console.log(BUCKET); var params = { Bucket: BUCKET, }; const obj = s3.listObjectsV2(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response })
有两个问题:
- 如何在S3存储桶间复制对象?需要结合使用getObject()和putObject()还是使用copyObject()?
- 为什么listObjectsV2仅返回100个对象且提示还有900个以上,实际对象总数更多,如何获取存储桶内的所有对象?
解答
问题1:跨桶复制对象的最优实现
优先使用copyObject()方法,这是AWS官方推荐的跨桶复制方案,优势如下:
- 无需将文件下载到本地,直接在AWS服务器端完成复制,节省带宽和本地资源
- 自动支持大对象(超过5GB)的分段复制,无需额外处理
- 代码更简洁,仅需一次API调用
示例代码:
// 复制单个对象的异步函数 async function copyS3Object(sourceBucket, sourceKey, targetBucket, targetKey) { const params = { Bucket: targetBucket, CopySource: `/${sourceBucket}/${sourceKey}`, Key: targetKey }; try { await s3.copyObject(params).promise(); console.log(`对象复制成功:${sourceKey}`); } catch (err) { console.error(`对象复制失败:${sourceKey}`, err); } } // 调用示例 copyS3Object('源存储桶名称', '源对象键', '目标存储桶名称', '目标对象键');
如果使用getObject() + putObject(),需要先将对象下载到内存/本地,再上传到目标桶,仅适合需要修改文件内容的场景,效率远低于copyObject(),不推荐直接用于跨桶复制。
问题2:获取存储桶所有对象的方法
listObjectsV2()默认单次最多返回1000个对象,当对象总数超过这个限制时,响应会返回NextContinuationToken标记。需要循环调用API,直到响应中没有NextContinuationToken,才能获取全部对象。
示例代码:
// 获取存储桶所有对象的异步函数 async function listAllS3Objects(bucketName) { let allObjects = []; let continuationToken = null; do { const params = { Bucket: bucketName, ContinuationToken: continuationToken }; const response = await s3.listObjectsV2(params).promise(); allObjects = allObjects.concat(response.Contents); continuationToken = response.NextContinuationToken; console.log(`已获取${allObjects.length}个对象`); } while (continuationToken); return allObjects; } // 调用示例 listAllS3Objects('你的存储桶名称') .then(objects => console.log('全部对象列表:', objects)) .catch(err => console.error('获取对象列表失败', err));
补充提示
如果存储桶内对象数量极大(十万级以上),建议添加批量异步复制逻辑,避免内存占用过高。
内容的提问来源于stack exchange,提问作者SJaka
相关产品推荐
相关产品推荐

