¿Cómo copio todos los objetos de un prefijo a otro? He intentado todas las formas posibles de copiar todos los objetos de una vez de un prefijo a otro, pero la única forma que parece funcionar es recorrer una lista de objetos y copiarlos uno por uno. Esto es realmente ineficiente. Si tengo cientos de archivos en una carpeta, ¿tendré que hacer 100 llamadas?
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 }]); } });Deberá crear un AWS.S3.listObjects() para enumerar sus objetos con un prefijo específico. Pero tiene razón en que deberá realizar una llamada para cada objeto que desee copiar de un depósito/prefijo al mismo u otro depósito/prefijo.
También puede usar una biblioteca de utilidades como async para administrar sus solicitudes.
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 = { Bucket: bucketName, CopySource: bucketName + '/' + file.Key, Key: file.Key.replace(oldPrefix, newPrefix) }; s3.copyObject(params, function(copyErr, copyData){ if (copyErr) { console.log(copyErr); } else { console.log('Copied: ', params.Key); cb(); } }); }, done); } });¡Espero que esto ayude!
Aquí hay un fragmento de código que lo hace de la manera "async await":
const AWS = require('aws-sdk'); AWS.config.update({ credentials: new AWS.Credentials(....), // credential parameters }); AWS.config.setPromisesDependency(require('bluebird')); const s3 = new AWS.S3(); ... ... const bucketName = 'bucketName'; // example bucket const folderToMove = 'folderToMove/'; // old folder name const destinationFolder = 'destinationFolder/'; // new destination folder try { const listObjectsResponse = await s3.listObjects({ Bucket: bucketName, Prefix: folderToMove, Delimiter: '/', }).promise(); const folderContentInfo = listObjectsResponse.Contents; const folderPrefix = listObjectsResponse.Prefix; await Promise.all( folderContentInfo.map(async (fileInfo) => { await s3.copyObject({ Bucket: bucketName, CopySource: `${bucketName}/${fileInfo.Key}`, // old file Key Key: `${destinationFolder}/${fileInfo.Key.replace(folderPrefix, '')}`, // new file Key }).promise(); await s3.deleteObject({ Bucket: bucketName, Key: fileInfo.Key, }).promise(); }) ); } catch (err) { console.error(err); // error handling }Más actualizaciones sobre el código original que copia carpetas de forma recursiva. Algunas limitaciones son que el código no maneja más de 1000 objetos por prefijo y, por supuesto, la limitación de profundidad si sus carpetas son muy profundas.
import AWS from 'aws-sdk'; AWS.config.update({ region: 'ap-southeast-1' }); /** * Copy s3 folder * @param {string} bucket Params for the first argument * @param {string} source for the 2nd argument * @param {string} dest for the 2nd argument * @returns {promise} the get object promise */ export default async function s3CopyFolder(bucket, source, dest) { // sanity check: source and dest must end with '/' if (!source.endsWith('/') || !dest.endsWith('/')) { return Promise.reject(new Error('source or dest must ends with fwd slash')); } const s3 = new AWS.S3(); // plan, list through the source, if got continuation token, recursive const listResponse = await s3.listObjectsV2({ Bucket: bucket, Prefix: source, Delimiter: '/', }).promise(); // copy objects await Promise.all( listResponse.Contents.map(async (file) => { await s3.copyObject({ Bucket: bucket, CopySource: `${bucket}/${file.Key}`, Key: `${dest}${file.Key.replace(listResponse.Prefix, '')}`, }).promise(); }), ); // recursive copy sub-folders await Promise.all( listResponse.CommonPrefixes.map(async (folder) => { await s3CopyFolder( bucket, `${folder.Prefix}`, `${dest}${folder.Prefix.replace(listResponse.Prefix, '')}`, ); }), ); return Promise.resolve('ok'); }