更新时间:2024-12-09 GMT+08:00
分段复制
分段复制是分段上传的一种特殊情况,即分段上传任务中的段通过复制OBS指定桶中现有对象(或对象的一部分)来实现。
您可以通过ObsClient->copyPart来复制段。
本示例用于分段复制桶名为“sourcebucketname”里的“sourceobjectname”对象到桶名为“destbucketname”里的“destobjectname”对象。
代码示例如下所示:
// 引入依赖库
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参数指定待复制的源对象的字节范围。
父主题: 上传对象