更新时间:2023-11-09 GMT+08:00
分段复制
分段复制是分段上传的一种特殊情况,即分段上传任务中的段通过复制OBS指定桶中现有对象(或对象的一部分)来实现。您可以通过ObsClient->copyPart来复制段。以下代码展示了如何使用分段复制模式复制大对象:
// 引入依赖库 require 'vendor/autoload.php'; // 使用源码安装时引入SDK代码库 // require 'obs-autoloader.php'; // 声明命名空间 use Obs\ObsClient; // 创建ObsClient实例 $obsClient = new ObsClient ( [ //推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。 //您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/usermanual-ca/ca_01_0003.html 'key' => getenv('ACCESS_KEY_ID'), 'secret' => getenv('SECRET_ACCESS_KEY'), 'endpoint' => 'https://your-endpoint' ] ); $destBucketName = 'destbucketname'; $destObjectKey = 'destobjectname'; $sourceBucketName = 'sourcebucketname'; $sourceObjectKey = 'sourceobjectname'; // 初始化分段上传任务 $resp = $obsClient->initiateMultipartUpload ( [ 'Bucket' => $destBucketName, 'Key' => $destObjectKey ] ); $uploadId = $resp ['UploadId']; printf ( "UploadId:%s\n\n", $uploadId ); // 获取大对象信息 $resp = $obsClient->getObjectMetadata ( [ 'Bucket' => $sourceBucketName, 'Key' => $sourceObjectKey ]); // 每段复制100MB $partSize = 100 * 1024 * 1024; $objectSize = $resp ['ContentLength']; // 计算需要复制的段数 $partCount = $objectSize % $partSize === 0 ? intval ( $objectSize / $partSize ) : intval ( $objectSize / $partSize ) + 1; // 执行并发复制段 $promise = null; $parts = []; for($i = 0; $i < $partCount; $i ++) { $rangeStart = $i * $partSize; $rangeEnd = ($i + 1 === $partCount) ? $objectSize - 1 : $rangeStart + $partSize - 1; $partNumber = $i + 1; $p = $obsClient->copyPartAsync ( [ 'Bucket' => $destBucketName, 'Key' => $destObjectKey, 'UploadId' => $uploadId, 'PartNumber' => $partNumber, 'CopySource' => sprintf ( '%s/%s', $sourceBucketName, $sourceObjectKey ), 'CopySourceRange' => sprintf ( 'bytes=%d-%d', $rangeStart, $rangeEnd ) ], function ($exception, $resp) use (&$parts, $partNumber) { $parts [] = [ 'PartNumber' => $partNumber, 'ETag' => $resp ['ETag'] ]; printf ( "Part#" . strval ( $partNumber ) . " done\n\n" ); } ); if ($promise === null) { $promise = $p; } } // 等待复制完成 $promise->wait (); usort ( $parts, function ($a, $b) { if ($a ['PartNumber'] === $b ['PartNumber']) { return 0; } return $a ['PartNumber'] > $b ['PartNumber'] ? 1 : - 1; } ); // 合并段 $resp = $obsClient->completeMultipartUpload ( [ 'Bucket' => $destBucketName, 'Key' => $destObjectKey, 'UploadId' => $uploadId, 'Parts' => $parts ] ); printf("Complete to upload multiparts finished, RequestId:%s\n", $resp['RequestId']);
复制段时,使用PartNumber参数指定分段号;使用UploadId参数指定分段上传任务的全局唯一标识;使用CopySource参数指定复制时的源对象信息;使用CopySourceRange参数指定待复制的源对象的字节范围。
父主题: 上传对象