Tous les produits
Search
Centre de documentation

Object Storage Service:Téléchargement en plusieurs parties (SDK C++)

Dernière mise à jour :Aug 18, 2026

Object Storage Service (OSS) propose une fonctionnalité de téléchargement en plusieurs parties pour les objets volumineux. Ce processus consiste à diviser un objet volumineux en parties plus petites, à les télécharger indépendamment, puis à appeler l'API CompleteMultipartUpload pour assembler les parties en un seul objet. Cette méthode permet de reprendre les téléchargements interrompus.

Notes

  • Cette rubrique utilise l'endpoint public de la région Chine (Hangzhou). Si vous souhaitez accéder à OSS depuis d'autres services Alibaba Cloud situés dans la même région, utilisez un endpoint interne. Pour plus d'informations sur les régions et les endpoints OSS, consultez la page Régions et endpoints.

  • Cette rubrique explique comment créer une instance OSSClient avec un endpoint OSS. Pour d'autres configurations, telles que l'utilisation d'un domaine personnalisé ou l'authentification via des identifiants du Security Token Service (STS), reportez-vous à la section Créer une instance OssClient.

  • Pour mener à bien l'intégralité du processus de téléchargement en plusieurs parties, qui inclut les opérations InitiateMultipartUpload, UploadPart et CompleteMultipartUpload, vous devez disposer de l'autorisation oss:PutObject. Pour en savoir plus, consultez la page Accorder des autorisations personnalisées à un utilisateur RAM.

Procédure

Le téléchargement en plusieurs parties s'effectue en trois étapes :

  1. Initiez un téléchargement en plusieurs parties.

    Appelez l'opération InitiateMultipartUpload pour obtenir un ID de téléchargement globalement unique auprès d'OSS.

  2. Téléchargez les parties.

    Appelez l'opération UploadPart pour télécharger les données de chaque partie.

    Remarque
    • Le numéro de partie identifie la position d'une partie au sein de l'objet. Le téléchargement de données avec le même numéro de partie écrase la partie existante.

    • OSS renvoie le hachage MD5 des données de la partie reçues dans l'en-tête ETag de la réponse.

    • OSS calcule le hachage MD5 des données téléchargées et le compare au hachage calculé par le SDK. En cas de non-concordance, le code d'erreur InvalidDigest est renvoyé.

  3. Finalisez le téléchargement en plusieurs parties.

    Une fois toutes les parties téléchargées, appelez l'opération CompleteMultipartUpload pour assembler les parties en un objet complet.

Exemple de code pour le téléchargement en plusieurs parties

L'exemple suivant illustre le processus complet de téléchargement en plusieurs parties :

#include <alibabacloud/oss/OssClient.h>
#include <fstream>

int64_t getFileSize(const std::string& file)
{
    std::fstream f(file, std::ios::in | std::ios::binary);
    f.seekg(0, f.end);
    int64_t size = f.tellg();
    f.close();
    return size;
}

using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
  
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
    /* (Optional) Set the storage class as shown in the following example. */
    //initUploadRequest.MetaData().addHeader("x-oss-storage-class", "Standard");

    /* Initiate the multipart upload event. */
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    /* You can cancel the multipart upload event or list uploaded parts based on the upload ID. */
    /* To cancel a multipart upload event based on the upload ID, obtain the upload ID after you call InitiateMultipartUpload to initiate the event. */
    /* To list uploaded parts based on the upload ID, obtain the upload ID after you call InitiateMultipartUpload but before you call CompleteMultipartUpload. */ 
    auto uploadId = uploadIdResult.result().UploadId();
    std::string fileToUpload = "yourLocalFilename";
    /* The minimum part size is 100 KB and the maximum part size is 5 GB. The size of the last part can be less than 100 KB. */
    int64_t partSize = 100 * 1024;
    PartList partETagList;
    auto fileSize = getFileSize(fileToUpload);
    int partCount = static_cast<int>(fileSize / partSize);
    /* Calculate the number of parts. */
    if (fileSize % partSize != 0) {
        partCount++;
    }

    /* Upload each part. */
    for (int i = 1; i <= partCount; i++) {
        auto skipBytes = partSize * (i - 1);
        auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
        std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(fileToUpload, std::ios::in|std::ios::binary);
        content->seekg(skipBytes, std::ios::beg);

        UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
        uploadPartRequest.setContentLength(size);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setPartNumber(i);
        auto uploadPartOutcome = client.UploadPart(uploadPartRequest);
        if (uploadPartOutcome.isSuccess()) {
            Part part(i, uploadPartOutcome.result().ETag());
            partETagList.push_back(part);
        }
        else {
            std::cout << "uploadPart fail" <<
            ",code:" << uploadPartOutcome.error().Code() <<
            ",message:" << uploadPartOutcome.error().Message() <<
            ",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
        }

    }

    /* Complete the multipart upload. */
    /* When you complete the multipart upload, you must provide all valid partETags. After OSS receives the partETags, OSS verifies each part. After all parts are verified, OSS combines them into a complete object. */
    CompleteMultipartUploadRequest request(BucketName, ObjectName);
    request.setUploadId(uploadId);
    request.setPartList(partETagList);
    /* (Optional) Set the access control list (ACL) as shown in the following example. */
    //request.setAcl(CannedAccessControlList::Private);

    auto outcome = client.CompleteMultipartUpload(request);

    if (!outcome.isSuccess()) {
        /* Handle the exception. */
        std::cout << "CompleteMultipartUpload fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Lorsque vous appelez l'opération CompleteMultipartUpload, vous devez fournir la valeur ETag de chaque partie. Vous pouvez obtenir la valeur ETag de chaque partie de l'une des manières suivantes :

  • Lors du téléchargement d'une partie, la réponse inclut la valeur ETag de cette partie. Vous pouvez enregistrer et utiliser cette valeur ETag. Cette méthode est utilisée dans l'exemple de code précédent.

  • Appelez l'opération ListParts pour interroger les valeurs ETag de toutes les parties téléchargées.

Répertorier les parties téléchargées

Appelez l'opération ListParts pour répertorier toutes les parties correctement téléchargées pour un ID de téléchargement spécifique.

Remarque

Par défaut, vous pouvez répertorier un maximum de 1 000 parties téléchargées à la fois. Si le nombre de parties téléchargées dépasse 1 000, vous devez les répertorier par page.

Répertorier les parties téléchargées

L'exemple de code suivant montre comment répertorier les parties téléchargées :

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Specify the upload ID. The upload ID is obtained from the response to the InitiateMultipartUpload operation. You must obtain the upload ID before you call the CompleteMultipartUpload operation. */
    std::string UploadId = "yourUploadId";

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* List uploaded parts. By default, a maximum of 1,000 parts are listed. */
    ListPartsRequest listuploadrequest(BucketName, ObjectName);
    listuploadrequest.setUploadId(UploadId);

    bool IsTruncated = false;

    do {
        auto listUploadResult = client.ListParts(listuploadrequest);
        if (!listUploadResult.isSuccess()) {
            /* Handle the exception. */
            std::cout << "ListParts fail" <<
            ",code:" << listUploadResult.error().Code() <<
            ",message:" << listUploadResult.error().Message() <<
            ",requestId:" << listUploadResult.error().RequestId() << std::endl;
            break;
        }
        else {
            for (const auto& part : listUploadResult.result().PartList()) {
                std::cout << "part"<<
                ",name:" << part.PartNumber() <<
                ",size:" << part.Size() <<
                ",etag:" << part.ETag() <<
                ",lastmodify time:" << part.LastModified() << std::endl;
            }
        }
        listuploadrequest.setPartNumberMarker(listUploadResult.result().NextPartNumberMarker());
        IsTruncated = listUploadResult.result().IsTruncated();
    } while (IsTruncated);

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Répertorier toutes les parties téléchargées par page

L'exemple de code suivant montre comment spécifier le nombre de parties à renvoyer sur chaque page et répertorier toutes les parties par page :

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Specify the upload ID. The upload ID is obtained from the response to the InitiateMultipartUpload operation. You must obtain the upload ID before you call the CompleteMultipartUpload operation. */
    std::string UploadId = "yourUploadId";

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* List all uploaded parts by page. */
    /* Set the maximum number of parts to return on each page. */
    ListPartsRequest listuploadrequest(BucketName, ObjectName);
    listuploadrequest.setMaxParts(50);
    listuploadrequest.setUploadId(UploadId);
    bool IsTruncated = false;
    do {
        auto listuploadresult = client.ListParts(listuploadrequest);
        if (!listuploadresult.isSuccess()) {
            /* Handle the exception. */
            std::cout << "ListParts fail" <<
            ",code:" << listuploadresult.error().Code() <<
            ",message:" << listuploadresult.error().Message() <<
            ",requestId:" << listuploadresult.error().RequestId() << std::endl;
            break;
        }
        else {
            for (const auto& part : listuploadresult.result().PartList()) {
                std::cout << "part"<<
                ",name:" << part.PartNumber() <<
                ",size:" << part.Size() <<
                ",etag:" << part.ETag() <<
                ",lastmodify time:" << part.LastModified() << std::endl;
            }
        }  
        listuploadrequest.setPartNumberMarker(listuploadresult.result().NextPartNumberMarker());
        IsTruncated = listuploadresult.result().IsTruncated();
    } while (IsTruncated);

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Répertorier les événements de téléchargement en plusieurs parties

Appelez l'opération ListMultipartUploads pour répertorier tous les événements de téléchargement en plusieurs parties en cours. Un événement de téléchargement en plusieurs parties en cours est un événement qui a été initié mais n'a pas encore été finalisé ni annulé.

Remarque

Par défaut, vous pouvez répertorier un maximum de 1 000 événements de téléchargement en plusieurs parties à la fois. Si le nombre d'événements dépasse 1 000, vous devez les répertorier par page.

Répertorier les événements de téléchargement en plusieurs parties

L'exemple de code suivant montre comment répertorier les événements de téléchargement en plusieurs parties.

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket";    

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* List upload events. By default, a maximum of 1,000 events are listed. */
    ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
	bool IsTruncated = false;
    do {
        auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
        if (!listresult.isSuccess()) {
            /* Handle the exception. */
            std::cout << "ListMultipartUploads fail" <<
            ",code:" << listresult.error().Code() <<
            ",message:" << listresult.error().Message() <<
            ",requestId:" << listresult.error().RequestId() << std::endl;
            break;
        }
        else {
            for (const auto& part : listresult.result().MultipartUploadList()) {
                std::cout << "part"<<
                ",name:" << part.Key <<
                ",uploadid:" << part.UploadId <<
                ",initiated time:" << part.Initiated << std::endl;
            }
        }
        listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker()); 
        listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
        IsTruncated = listresult.result().IsTruncated();
    } while (IsTruncated);

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Répertorier tous les événements de téléchargement par page

L'exemple de code suivant montre comment répertorier tous les événements de téléchargement par page :

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket"; 

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* List all upload events by page. */
    /* Set the maximum number of upload events to return on each page. */
    ListMultipartUploadsRequest  listmultiuploadrequest(BucketName);
    listmultiuploadrequest.setMaxUploads(50);
    bool IsTruncated = false;
    do {
        auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
        if (!listresult.isSuccess()) {
            /* Handle the exception. */
            std::cout << "ListMultipartUploads fail" <<
            ",code:" << listresult.error().Code() <<
            ",message:" << listresult.error().Message() <<
            ",requestId:" << listresult.error().RequestId() << std::endl;
            break;
        }
        else {
            for (const auto& part : listresult.result().MultipartUploadList()) {
                std::cout << "part"<<
                ",name:" << part.Key <<
                ",uploadid:" << part.UploadId <<
                ",initiated time:" << part.Initiated << std::endl;
            }
        }  
        listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker()); 
        listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
        IsTruncated = listresult.result().IsTruncated();
    } while (IsTruncated);

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Annuler un événement de téléchargement en plusieurs parties

Vous pouvez appeler l'opération client.AbortMultipartUpload pour annuler un événement de téléchargement en plusieurs parties. Une fois l'événement annulé, vous ne pouvez plus utiliser l'ID de téléchargement pour aucune opération. Les parties déjà téléchargées sont également supprimées.

L'exemple de code suivant montre comment annuler un événement de téléchargement en plusieurs parties :

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
    
    /* Set Endpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set Region to the region in which the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Specify the upload ID. The upload ID is obtained from the response to the InitiateMultipartUpload operation. */
    std::string UploadId = "yourUploadId";

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
  
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);

    /* Initiate the multipart upload event. */
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    auto uploadId = uploadIdResult.result().UploadId();

    /* Cancel the multipart upload event. */
    AbortMultipartUploadRequest  abortUploadRequest(BucketName, ObjectName, uploadId);
    auto outcome = client.AbortMultipartUpload(abortUploadRequest);

    if (!outcome.isSuccess()) {
        /* Handle the exception. */
        std::cout << "AbortMultipartUpload fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}

Références

  • Pour l'exemple de code complet relatif au téléchargement en plusieurs parties, consultez l'exemple GitHub.

  • Un téléchargement en plusieurs parties implique trois opérations API :

  • Pour plus d'informations sur l'opération API utilisée pour abandonner un événement de téléchargement en plusieurs parties, consultez la page AbortMultipartUpload.

  • Pour plus d'informations sur l'opération API utilisée pour répertorier les parties téléchargées, consultez la page ListUploadedParts.

  • Pour plus d'informations sur l'opération API utilisée pour répertorier tous les événements de téléchargement en plusieurs parties en cours (événements initiés mais ni finalisés ni abandonnés), consultez la page ListMultipartUploads.