You need to enable JavaScript to run this app.
导航

分片拷贝(C++ SDK)

最近更新时间2024.02.04 18:31:04

首次发布时间2023.01.29 15:35:46

对象大于 5GiB 时,您可以使用 uploadPartCopy 接口进行分片拷贝。

注意事项

  • 拷贝文件不支持跨区域的桶间拷贝。
  • 拷贝对象时,账号必须具备源对象的读取权限和目标桶的写入权限。
  • 拷贝对象时,可以保留所有元数据(默认值)或指定新的元数据。但 ACL 并未被保留,而是设置为私有。

分片拷贝步骤

对象大于 5GiB 时,需要使用 uploadPartCopy 来进行分片拷贝,包括三个步骤:

  1. 通过 createMultipartUpload 初始化分片拷贝任务。
  2. 通过 uploadPartCopy 进行分片拷贝。
  3. 通过 completeMultipartUpload 合并分片。

示例代码

以下代码用于将 srcbucket 桶中 srcdir/exampleobject.txt 对象拷贝到 destbucket 桶中,并设置对象对象名为 destdir/exampleobject.txt

#include "TosClientV2.h"
using namespace VolcengineTos;
int main(void){
    // 初始化 TOS 账号信息
    // Your Region 填写 Bucket 所在 Region
    std::string region = "Your Region";
    std::string accessKey = std::getenv("TOS_ACCESS_KEY");
    std::string secretKey = std::getenv("TOS_SECRET_KEY");
    // 填写 Bucket 名称,例如 destbucket
    std::string bucketName = "destbucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,destdir/exampleobject.txt。
    std::string objectName = "destdir/exampleobject.txt";
    // 填写 Bucket 名称,例如 srcbucket
    std::string srcBucketName = "srcbucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,srcdir/exampleobject.txt。
    std::string srcObjectName = "srcdir/exampleobject.txt";
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    CreateMultipartUploadInput input_part_create(bucketName, objectName);
    auto upload = client.createMultipartUpload(input_part_create);
    if (!upload.isSuccess()) {
        std::cout << "createMultipartUpload error: " << upload.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    // 获取要copy的对象大小
    HeadObjectV2Input headInput(srcBucketName, srcObjectName);
    auto headOutput = client.headObject(headInput);
    if (!headOutput.isSuccess()) {
        std::cout << "head object error: " << headOutput.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    int64_t objectSize = headOutput.result().getContentLength();
    // 分片大小 5MB 为例
    int partSize = 5 * 1024 * 1024;
    int partCount = (int)(objectSize / partSize);
    std::vector<UploadedPartV2> copyParts;
    // 计算分片个数。
    if (objectSize % partSize != 0) {
        partCount++;
    }
    int64_t copySourceRangeEnd_ = 0;
    // 对每一个分片进行拷贝。
    for (int i = 1; i <= partCount; i++) {
        auto offset = partSize * (i - 1);
        auto size = (partSize < objectSize - offset) ? partSize : (objectSize - offset);
        UploadPartCopyV2Input input(bucketName, objectName, srcBucketName, srcObjectName, i,upload.result().getUploadId());
        input.setCopySourceRangeStart(offset);
        input.setCopySourceRangeEnd(offset + size - 1);
        auto output = client.uploadPartCopy(input);
        if (!output.isSuccess()) {
            std::cout << "upload part " << i << "failed, error is: " << output.error().String() << std::endl;
            // 释放网络等资源
            CloseClient();
            return -1;
        }
        UploadedPartV2 temp(output.result().getPartNumber(), output.result().getETag());
        copyParts.push_back(temp);
    }
    CompleteMultipartUploadV2Input input(bucketName, objectName, upload.result().getUploadId(), copyParts);
    auto complete = client.completeMultipartUpload(input);
    if (!complete.isSuccess()) {
        std::cout << "CompleteMultipartUpload error: " << complete.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    // 释放网络等资源
    CloseClient();
    return 0;
}

相关文档