Multipart upload (C++ SDK V2)

更新时间:
复制 MD 格式

Multipart upload splits a large file into smaller parts that are uploaded independently. Use the OSS C++ SDK V2 to perform multipart uploads for files larger than 5 GB.

Notes

  • Before running the sample code, replace <region> with your region, such as cn-hangzhou.

  • The sample code uses environment variables to obtain access credentials.

  • To perform a multipart upload, you must have the oss:PutObject permission.

  • Multipart upload is recommended for files larger than 5 GB.

Sample code

Complete multipart upload

Perform a multipart upload in three steps: InitiateMultipartUpload, UploadPart, and CompleteMultipartUpload.

#include <iostream>
#include <vector>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    std::string bucketName = "examplebucket";
    std::string objectName = "exampledir/exampleobject.txt";

    // Step 1: Initiate the multipart upload.
    auto initOutcome = client.initiateMultipartUpload(
        oss::models::InitiateMultipartUploadRequest()
            .setBucket(bucketName)
            .setKey(objectName));

    if (!initOutcome.has_value()) {
        auto& e = initOutcome.error();
        std::cerr << "Failed to initiate the multipart upload"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    std::string uploadId = initOutcome.value().getUploadId();
    std::cout << "Multipart upload initiated successfully, uploadId: " << uploadId << std::endl;

    // Step 2: Upload parts.
    std::vector<oss::models::Part> parts;

    // Upload part 1.
    std::string partData1(100 * 1024, 'a');
    auto partOutcome1 = client.uploadPart(
        oss::models::UploadPartRequest()
            .setBucket(bucketName)
            .setKey(objectName)
            .setUploadId(uploadId)
            .setPartNumber(1)
            .setBody(oss::RequestBody::fromString(partData1)));

    if (!partOutcome1.has_value()) {
        auto& e = partOutcome1.error();
        std::cerr << "Failed to upload part 1"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    parts.push_back(oss::models::Part()
        .setETag(partOutcome1.value().getETag())
        .setPartNumber(1));
    std::cout << "Part 1 uploaded successfully, eTag: " << partOutcome1.value().getETag() << std::endl;

    // Upload part 2.
    std::string partData2(100 * 1024, 'b');
    auto partOutcome2 = client.uploadPart(
        oss::models::UploadPartRequest()
            .setBucket(bucketName)
            .setKey(objectName)
            .setUploadId(uploadId)
            .setPartNumber(2)
            .setBody(oss::RequestBody::fromString(partData2)));

    if (!partOutcome2.has_value()) {
        auto& e = partOutcome2.error();
        std::cerr << "Failed to upload part 2"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    parts.push_back(oss::models::Part()
        .setETag(partOutcome2.value().getETag())
        .setPartNumber(2));
    std::cout << "Part 2 uploaded successfully, eTag: " << partOutcome2.value().getETag() << std::endl;

    // Step 3: Complete the multipart upload.
    oss::models::CompleteMultipartUpload complete;
    complete.parts = parts;

    auto completeOutcome = client.completeMultipartUpload(
        oss::models::CompleteMultipartUploadRequest()
            .setBucket(bucketName)
            .setKey(objectName)
            .setUploadId(uploadId)
            .setCompleteMultipartUpload(complete));

    if (!completeOutcome.has_value()) {
        auto& e = completeOutcome.error();
        std::cerr << "Failed to complete the multipart upload"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    std::cout << "Multipart upload completed"
              << ", requestId: " << completeOutcome.value().getRequestId() << std::endl;
    return 0;
}
          

Abort a multipart upload

Call AbortMultipartUpload to cancel an in-progress multipart upload task:

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto outcome = client.abortMultipartUpload(
        oss::models::AbortMultipartUploadRequest()
            .setBucket("examplebucket")
            .setKey("exampledir/exampleobject.txt")
            .setUploadId("your-upload-id"));

    if (!outcome.has_value()) {
        auto& e = outcome.error();
        std::cerr << "Failed to abort the multipart upload"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    std::cout << "Multipart upload aborted successfully"
              << ", requestId: " << outcome.value().getRequestId() << std::endl;
    return 0;
}
          

List uploaded parts in a single request

Call listParts to list uploaded parts. Each upload ID can have up to 10,000 parts. A single call returns up to maxParts parts (default: 1,000; maximum: 1,000). To retrieve all parts, use the Paginator pattern in the next section.

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto outcome = client.listParts(
        oss::models::ListPartsRequest()
            .setBucket("examplebucket")
            .setKey("exampledir/exampleobject.txt")
            .setUploadId("your-upload-id"));

    if (!outcome.has_value()) {
        auto& e = outcome.error();
        std::cerr << "Failed to list parts"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    auto& result = outcome.value();
    std::cout << "List of uploaded parts:" << std::endl;
    for (const auto& part : result.getParts()) {
        std::cout << "  Part Number: " << part.partNumber
                  << ", Size: " << part.size
                  << ", ETag: " << part.eTag << std::endl;
    }
    return 0;
}
          

List all uploaded parts with a paginator

Use a Paginator to iterate through all uploaded parts of a multipart upload task with automatic pagination.

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/Paginator.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto paginator = oss::makePaginator(client,
        oss::models::ListPartsRequest()
            .setBucket("examplebucket")
            .setKey("exampledir/exampleobject.txt")
            .setUploadId("your-upload-id"));

    int pageNum = 0;
    int totalParts = 0;
    while (paginator.hasNext()) {
        auto outcome = paginator.nextPage();
        if (!outcome.has_value()) {
            auto& e = outcome.error();
            std::cerr << "Failed to list parts"
                      << ", code: " << e.getCode()
                      << ", message: " << e.getMessage()
                      << ", requestId: " << e.getRequestId() << std::endl;
            return 1;
        }
        auto& result = outcome.value();
        pageNum++;
        std::cout << "Page " << pageNum << ", isTruncated: " << result.getIsTruncated() << std::endl;
        for (const auto& p : result.getParts()) {
            std::cout << "  Part Number: " << p.partNumber
                      << ", Size: " << p.size
                      << ", ETag: " << p.eTag << std::endl;
            totalParts++;
        }
    }
    std::cout << "A total of " << totalParts << " parts across " << pageNum << " pages." << std::endl;
    return 0;
}
          

List multipart upload tasks in a single request

Call listMultipartUploads to list ongoing multipart upload tasks in a bucket. A single call returns up to maxUploads tasks (default: 1,000; maximum: 1,000). To retrieve all tasks, use the Paginator pattern in the next section.

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto outcome = client.listMultipartUploads(
        oss::models::ListMultipartUploadsRequest()
            .setBucket("examplebucket")
            .setMaxUploads(100));

    if (!outcome.has_value()) {
        auto& e = outcome.error();
        std::cerr << "Failed to list multipart upload tasks"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    auto& result = outcome.value();
    std::cout << "Multipart upload tasks listed successfully"
              << ", status: " << result.getStatusCode()
              << ", isTruncated: " << result.getIsTruncated() << std::endl;

    for (const auto& u : result.getUploads()) {
        std::cout << "  Key: " << u.key
                  << ", uploadId: " << u.uploadId
                  << ", initiated: " << u.initiated << std::endl;
    }
    return 0;
}
          

List all upload tasks with a paginator

Use a Paginator to iterate through all ongoing multipart upload tasks in a bucket with automatic pagination.

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/Paginator.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto paginator = oss::makePaginator(client,
        oss::models::ListMultipartUploadsRequest()
            .setBucket("examplebucket")
            .setMaxUploads(100));

    int pageNum = 0;
    int totalUploads = 0;
    while (paginator.hasNext()) {
        auto outcome = paginator.nextPage();
        if (!outcome.has_value()) {
            auto& e = outcome.error();
            std::cerr << "Failed to list multipart upload tasks"
                      << ", code: " << e.getCode()
                      << ", message: " << e.getMessage()
                      << ", requestId: " << e.getRequestId() << std::endl;
            return 1;
        }
        auto& result = outcome.value();
        pageNum++;
        std::cout << "Page " << pageNum << ", isTruncated: " << result.getIsTruncated() << std::endl;
        for (const auto& u : result.getUploads()) {
            std::cout << "  Key: " << u.key
                      << ", uploadId: " << u.uploadId
                      << ", initiated: " << u.initiated << std::endl;
            totalUploads++;
        }
    }
    std::cout << "A total of " << totalUploads << " multipart upload tasks across " << pageNum << " pages." << std::endl;
    return 0;
}
          

Copy a part

Use UploadPartCopy to upload a part by copying data from an existing object. This is useful for copying large files between buckets.

#include <iostream>
#include "alibabacloud/oss2/ClientConfiguration.h"
#include "alibabacloud/oss2/OSSClient.h"
#include "alibabacloud/oss2/credentials/CredentialsProvider.h"

namespace oss = alibabacloud::oss2;

int main() {
    auto conf = oss::ClientConfiguration::loadDefault();
    conf.region = "<region>";
    conf.credentialsProvider = std::make_shared<oss::EnvironmentVariableCredentialsProvider>();

    oss::OSSClient client(conf);

    auto outcome = client.uploadPartCopy(
        oss::models::UploadPartCopyRequest()
            .setBucket("examplebucket")
            .setKey("exampleobject.txt")
            .setUploadId("your-upload-id")
            .setPartNumber(1)
            .setSourceBucket("sourcebucket")
            .setSourceKey("sourceobject.txt"));

    if (!outcome.has_value()) {
        auto& e = outcome.error();
        std::cerr << "Failed to copy the part"
                  << ", code: " << e.getCode()
                  << ", message: " << e.getMessage()
                  << ", requestId: " << e.getRequestId() << std::endl;
        return 1;
    }

    auto& result = outcome.value();
    std::cout << "Part copied successfully"
              << ", status: " << result.getStatusCode()
              << ", eTag: " << result.getETag()
              << ", lastModified: " << result.getLastModified() << std::endl;
    return 0;
}
          

Related documentation