如何使用AWS SDK for Node.js将Amazon S3中的所有对象从一个前缀复制/移动到另一个前缀

如何将所有对象从一个前缀复制到另一个前缀? 我已经尝试了所有可能的方法将一个镜头中的所有对象从一个前缀复制到另一个镜头,但似乎工作的唯一方法是循环一个对象列表并逐一复制它们。 这实在是效率低下。 如果我有一个文件夹中的数百个文件,我将不得不打100个电话?

var params = { Bucket: bucket, CopySource: bucket+'/'+oldDirName+'/filename.txt', Key: newDirName+'/filename.txt', }; s3.copyObject(params, function(err, data) { if (err) { callback.apply(this, [{ type: "error", message: "Error while renaming Directory", data: err }]); } else { callback.apply(this, [{ type: "success", message: "Directory renamed successfully", data: data }]); } }); 

您将需要使一个AWS.S3.listObjects()以特定的前缀列出您的对象。 但是你是正确的,因为你需要为每一个你想要从一个桶/前缀复制到同一个或另一个桶/前缀的对象进行一次调用。

您也可以使用像async这样的工具库来pipe理您的请求。

 var AWS = require('aws-sdk'); var async = require('async'); var bucketName = 'foo'; var oldPrefix = 'abc/'; var newPrefix = 'xyz/'; var s3 = new AWS.S3({params: {Bucket: bucketName}, region: 'us-west-2'}); var done = function(err, data) { if (err) console.log(err); else console.log(data); }; s3.listObjects({Prefix: oldPrefix}, function(err, data) { if (data.Contents.length) { async.each(data.Contents, function(file, cb) { var params = { CopySource: bucketName + '/' + file.Key, Key: file.Key.replace(oldPrefix, newPrefix) }; s3.copyObject(params, function(copyErr, copyData){ if (copyErr) { console.log(err); } else { console.log('Copied: ', params.Key); cb(); } }); }, done); } }); 

希望这可以帮助!

对Aditya Manohar代码的一个小改动,改进了s3.copyObject函数中的error handling,并且通过在复制请求执行后删除源文件来实际完成“移动”请求:

 const AWS = require('aws-sdk'); const async = require('async'); const bucketName = 'foo'; const oldPrefix = 'abc/'; const newPrefix = 'xyz/'; const s3 = new AWS.S3({ params: { Bucket: bucketName }, region: 'us-west-2' }); // 1) List all the objects in the source "directory" s3.listObjects({ Prefix: oldPrefix }, function (err, data) { if (data.Contents.length) { // Build up the paramters for the delete statement let paramsS3Delete = { Bucket: bucketName, Delete: { Objects: [] } }; // Expand the array with all the keys that we have found in the ListObjects function call, so that we can remove all the keys at once after we have copied all the keys data.Contents.forEach(function (content) { paramsS3Delete.Delete.Objects.push({ Key: content.Key }); }); // 2) Copy all the source files to the destination async.each(data.Contents, function (file, cb) { var params = { CopySource: bucketName + '/' + file.Key, Key: file.Key.replace(oldPrefix, newPrefix) }; s3.copyObject(params, function (copyErr, copyData) { if (copyErr) { console.log(err); } else { console.log('Copied: ', params.Key); } cb(); }); }, function (asyncError, asyncData) { // All the requests for the file copy have finished if (asyncError) { return console.log(asyncError); } else { console.log(asyncData); // 3) Now remove the source files - that way we effectively moved all the content s3.deleteObjects(paramsS3Delete, (deleteError, deleteData) => { if (deleteError) return console.log(deleteError); return console.log(deleteData); }) } }); } }); 

请注意,我已经将cb()callback函数移到了if-then-else循环之外。 这样,即使发生错误,asynchronous模块也会触发done()函数。