环回:如何将文件从一个容器复制到另一个容器?

时间:2016-09-06 16:02:17

标签: node.js loopbackjs strongloop

我使用Strongloop loopback作为我的后端API。 我正在使用loopback-component-storage上传和管理文件。更具体地说,我目前正在使用文件系统,但在生产时将切换到AWS存储。

平台上的用户可以复制项目,因此也会复制已上载的链接文件。

我的问题是,如何将文件从一个容器复制到另一个容器?<​​/ strong>

到目前为止,我的代码是创建一个新容器:

    Project.app.models.storage.getContainer(templateId, function (err, container) {
    if(err){
        // If error, no docs have been added or created, so just skip                        
        return;
    }
    Project.app.models.storage.createContainer({ name: projectId},function (err,container) {
    if(err){
       console.log("Error creating a container when copying project");
       return;
    }
    // Here is where I need assistance
    });
});

2 个答案:

答案 0 :(得分:3)

可以创建下载流然后将其传输到上传流从一个容器到另一个容器,但这不是一个好主意,因为您将创建不必要的流量。让您的基础环境为您完成工作。

在本地开发环境中,您可以使用fs模块处理文件,但在将存储迁移到S3时,应使用AWS SDK复制文件。您可以在Storage模型上创建远程方法,该方法将使源存储桶/文件夹和目标存储桶/文件夹为您复制文件。

类似的东西:

  Storage.remoteMethod(
    'copyS3File',
    {
      accepts: [
        {arg: 'copySource', type: 'string'},
        {arg: 'destinationBucket', type: 'string'},
        {arg: 'destinationFileName', type: 'string'}],
      returns: {arg: 'success', type: 'string'}
    }
  );

  Storage.copyS3File = function(copySource, destinationBucket, destinationFileName, cb) {
    var AWS = require('aws-sdk');
    var s3 = new AWS.S3({params: {Bucket: 'yourbucket',region:'yourregion'}});
    var params = {CopySource: copySource, Bucket: destinationBucket, Key: destinationFileName};
    s3.copyObject(params, function(err, success) {
      if (err) cb(err); // an error occurred
      else     cb(null, success)           // successful response
    });
  });

请参阅S3上的Calling the copyObject operation

请注意,此代码未经过测试或可以投放使用。这里只是为了让您了解如何做到这一点。

另请注意,S3与loopbackjs存储的实现有些不同。 S3具有扁平结构,但使用密钥名称前缀支持在文件夹中组织文件。

Working with S3 folders

为了更清楚,您可以从源容器中检索文件列表并循环遍历该列表,以使用上面创建的远程方法将文件复制到新目标:

Storage.getFiles({container: 'yourContainer'}, function(files){

  files.forEach(function(file){
    Storage.copyS3File(file.container + '/' + file.name, 'newContainer', 'newFile.name', cb);
  });

}, function(err){
  console.log(err);
});

答案 1 :(得分:1)

为文件系统提供程序

执行此操作的想法
  1. 使用storage.GetFiles('container-name',callback)
  2. 从容器中获取要复制文件的文件列表
  3. 使用存储创建要在其中复制这些文件的容器。 createContainer()
  4. 使用storage.uploadStream('recent-created-container','file-name')获取上传流
  5. 获取文件的读取流并管道读取和写入操作
  6. 为每个文件重复步骤3和步骤4(或者如果需要,可以链接流)
  7. 在您的情况下,代码看起来像

    Project.app.models.storage.getContainer(templateId, function (err, container) {
        if(err || !container){
            // If error, no docs have been added or created, so just skip
            return;
        }
        Project.app.models.storage.getFiles(templateId, function (err, files) {
            if(err){
                // If error, no docs have been added or created, so just skip
                return;
            }
          Project.app.models.storage.createContainer({ name: projectId},function (err,newcontainer) {
            if(err || !newcontainer){
               console.log("Error creating a container when copying project");
               return;
             }
             files.forEach(function(file){
               var writer = container.uploadStream(newcontainer.name, file.name);
                require('fs').createReadStream('path-to-storage-directory/'+container.name+'/'+file.name).pipe(writer);
                writer.on('finish', function(err,done){
                  console.log('finished writing file'+file.name)
                });
                writer.on('error', function(err){
                  console.log('error in copying file'+file.name,err)
                });
             });
          });
      })
    })