分段复制
开发过程中,您有任何问题可以在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参数指定待复制的源对象的字节范围。