更新时间:2023-11-08 GMT+08:00
分享

分段复制

开发过程中,您有任何问题可以在github上提交issue,或者在华为云对象存储服务论坛中发帖求助。接口参考文档详细介绍了每个接口的参数和使用方法。

分段复制是分段上传的一种特殊情况,即分段上传任务中的段通过复制OBS指定桶中现有对象(或对象的一部分)来实现。您可以通过ObsClient.copyPart来复制段。以下代码展示了如何使用分段复制模式复制大对象:

// 引入obs库
// 使用npm安装
var ObsClient = require('esdk-obs-nodejs');
// 使用源码安装
// var ObsClient = require('./lib/obs');

// 创建ObsClient实例
var obsClient = new ObsClient({
       //推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
       //您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
       access_key_id: process.env.ACCESS_KEY_ID,
       secret_access_key: process.env.SECRET_ACCESS_KEY,
       server : 'https://your-endpoint'
});

var destBucketName = 'destbucketname';
var destObjectKey = 'destobjectname';
var sourceBucketName = 'sourcebucketname';
var sourceObjectKey = 'sourceobjectname';

// 初始化分段上传任务
obsClient.initiateMultipartUpload({
       Bucket : destBucketName,
       Key : destObjectKey
}, (err, result) => {
       if(!err && result.CommonMsg.Status < 300){
              var uploadId = result.InterfaceResult.UploadId;
              console.log('\t' + uploadId + '\n');
              
              // 获取大对象信息
              obsClient.getObjectMetadata({
                     Bucket : sourceBucketName,
                     Key : sourceObjectKey
              }, (err, result) => {
                     if(!err && result.CommonMsg.Status < 300){
                           // 每段复制100MB
                           var partSize = 100 * 1024 * 1024;
                           var objectSize = Number(result.InterfaceResult.ContentLength);
                           
                           // 计算需要复制的段数
                           var partCount = objectSize % partSize === 0 ? Math.floor(objectSize / partSize) : Math.floor(objectSize / partSize) + 1;
                           
                           var events = require('events');
                           var eventEmitter = new events.EventEmitter();
                           var parts = [];
                           
                           // 执行并发复制段
                           for(let i=0;i<partCount;i++){
                                  let rangeStart = i * partSize;
                                  let rangeEnd = (i + 1) === partCount ? objectSize - 1 : rangeStart + partSize - 1;
                                  let partNumber = i + 1;
                                  obsClient.copyPart({
                                         Bucket: destBucketName,
                                         Key: destObjectKey,
                                         PartNumber : partNumber,
                                         UploadId : uploadId,
                                         CopySource: sourceBucketName + '/' + sourceObjectKey,
                                         CopySourceRange : 'bytes=' + rangeStart + '-' + rangeEnd
                                  }, (err, result) => {
                                         if(!err && result.CommonMsg.Status < 300){
                                                parts.push({PartNumber : partNumber, ETag : result.InterfaceResult.ETag});
                                                if(parts.length === partCount){
                                                       var _parts = parts.sort((a, b) => {
                                                              if(a.PartNumber >= b.PartNumber){
                                                                     return 1;
                                                              }
                                                              return -1;
                                                       });
                                                       eventEmitter.emit('copy part finished', _parts);
                                                }
                                         }else{
                                                throw new Error(err || result.CommonMsg.Code);
                                         }
                                  });
                           }
                           
                           // 等待复制完成
                           eventEmitter.on('copy part finished', (parts) => {
                                  // 合并段
                                  obsClient.completeMultipartUpload({
                                         Bucket: destBucketName,
                                         Key: destObjectKey,
                                         UploadId: uploadId,
                                         Parts: parts
                                  }, (err, result) => {
                                         if(!err && result.CommonMsg.Status < 300){
                                                console.log('Complete to upload multiparts finished.\n');
                                         }
                                  });
                           });
                     }
              });
       }
});

复制段时,使用PartNumber参数指定分段号;使用UploadId参数指定分段上传任务的全局唯一标识;使用CopySource参数指定复制时的源对象信息;使用CopySourceRange参数指定待复制的源对象的字节范围。

分享:

    相关文档

    相关产品