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

普通上传(C++ SDK)

最近更新时间2024.02.04 18:30:56

首次发布时间2022.04.08 10:56:30

普通上传是指通过 putObject 方法上传单个对象(Object),支持上传字符串(字符流)和上传本地文件。流式上传是指使用文件流等流式数据或字符串作为 TOS 的数据源,其统一抽象为 iostream 进行上传。文件上传是指使用本地文件作为 TOS 的数据源。本章节介绍如何使用流式上传和文件上传方式上传您的数据。上传对象时,如果桶中已经存在同名对象,则新的对象会覆盖已有的对象。桶开启多版本的场景下,则会保留原有对象,生成一个新的版本号用于标识新上传的对象。

注意事项

  • 上传对象前,您必须具有 tos:PutObject 权限,具体操作,请参见权限配置指南
  • 上传对象时,对象名必须满足一定规范,详细信息,请参见对象命名规范
  • TOS 是面向海量存储设计的分布式对象存储产品,内部分区存储了对象索引数据。为横向扩展您上传对象和下载对象时的最大吞吐量和减小热点分区的概率,请您避免使用字典序递增的对象命名方式,详细信息,请参见性能优化
  • 如果桶中已经存在同名对象,则新对象会覆盖已有的对象。如果您的桶开启了版本控制,则会保留原有对象,并生成一个新版本号用于标识新上传的对象。

文件夹说明

  • 如果您希望上传对象到某个文件夹(对象存储的逻辑概念)下,可以为对象名添加以 / 结尾的前缀,且支持多级文件夹,例如对象名 folder1/folder2/objectName 是指将 objectName 上传到 folder1 文件夹下的 folder2 文件夹下。
  • 上传对象到某个文件夹时,由于文件夹只是对象存储的逻辑概念,因此实际上不会在对象存储服务端生成真实的文件夹。

示例代码

上传字符串

以下代码用于将字符串上传到目标桶 examplebucket 中的 exampledir/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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    // 需要上传的对象数据,以 stringstream 的形式上传
    std::string data("Object data to be uploaded");
    auto ss = std::make_shared<std::stringstream>(data);
    PutObjectV2Input input(bucketName, objectName, ss);
    auto output = client.putObject(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObject failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObject success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

从本地文件流上传

以下代码用于从本地文件流上传到目标桶 examplebucket 中的 exampledir/exampleobject.txt 对象。

#include <fstream>
#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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    // 填写本地文件完整路径,例如/localpath/examplefile.txt,其中localpath为本地文件examplefile.txt所在本地路径
    std::string filePath = "/localpath/examplefile.txt";
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    // 需要上传的对象数据,以 fileStream 的形式上传
    auto content = std::make_shared<std::fstream>(filePath, std::ios::in | std::ios_base::binary);
    PutObjectV2Input input(bucketName, objectName, content);
    auto output = client.putObject(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObjectFromFileContent failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObjectFromFileContent success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

上传本地文件

以下代码用于将本地文件上传到目标桶 examplebucket 中的 exampledir/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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    // 填写本地文件完整路径,例如/localpath/examplefile.txt,其中localpath为本地文件examplefile.txt所在本地路径
    std::string filePath = "/localpath/examplefile.txt";
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    PutObjectFromFileInput input(bucketName, objectName, filePath);
    auto output = client.putObjectFromFile(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObjectWithMetaData failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObjectWithMetaData success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

遍历本地文件夹并上传到桶中

#include "TosClientV2.h"
#include <dirent.h>
using namespace VolcengineTos;

static void GenerateFilePaths(const std::string& folderPath,std::vector<std::string>& filePaths){
    struct dirent *dirp;
    DIR *dp = opendir(folderPath.c_str());
    if(dp == nullptr){
        return;
    }
    while((dirp = readdir(dp)) != nullptr){
        // 文件
        if(dirp->d_type == 8){
            std::string fileName = dirp->d_name;
            std::string filePath = folderPath + fileName;
            filePaths.push_back(filePath);
        }
        // 文件夹
        if(dirp->d_type == 4){
            std::string folderName = dirp->d_name;
            // Linux 路径下的 . 和 .. 需要忽略
            if(folderName != "." && folderName != ".."){
                std::string NewfolderPath = folderPath + folderName + "/";
                mkFilePaths(NewfolderPath,filePaths);
            }
        }
    }
    closedir(dp);
}
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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    // 填写本地文件夹完整路径,例如/localpath/
    std::string folderPath = "/localpath/";
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);

    std::vector<std::string> filePaths;
    // 生成要上传的文件的绝对路径集合
    GenerateFilePaths(folderPath,filePaths);
    PutObjectFromFileInput input(bucketName);
    for (auto& filePath : filePaths ){
        input.setKey(filePath);
        input.setFilePath(filePath);
        auto output = client.putObjectFromFile(input);
        if (!output.isSuccess()) {
            // 异常处理
            std::cout << "PutObjectFromFile failed. the object name:" << filePath << std::endl;
            std::cout << "PutObjectFromFile failed." << output.error().String() << std::endl;
        }
        std::cout << "PutObjectFromFile success. the object name:" << filePath << std::endl;
    }
    
    
    // 释放网络等资源
    CloseClient();
    return 0;

};

上传对象时指定 ACL、StorageClass、对象元数据等

当进行流式上传或文件上传时,SDK 支持通过设置待上传对象的 ACL、元数据。

说明

对象的 ACL、StorageClass、对象元数据参数均为可选,请根据实际情况进行选择。

以下代码用于将字符流上传到目标桶 examplebucket 中的 exampledir/exampleobject.txt 对象,同时指定对象的 ACL、StorageClass、对象元数据等参数。

#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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    // 需要上传的对象数据,以 stringstream 的形式上传
    std::string data("Object data to be uploaded");
    auto ss = std::make_shared<std::stringstream>(data);
    PutObjectV2Input input(bucketName, objectName, ss);
    // 设置 ACL 为 PublicRead
    input.setAcl(ACLType::PublicRead);
    // 设置 StorageClass 为 IA
    input.setStorageClass(StorageClassType::IA);
    // 设置对象元数据
    input.setMeta({{"self-test", "yes"}});
    // 设置ContentType
    input.setContentType("application/json");
    
    auto output = client.putObject(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObjectWithMetaData failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObjectWithMetaData success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

进度条处理

以下代码以上传字符串为例,介绍如何使用进度条。

#include "TosClientV2.h"
using namespace VolcengineTos;

// 使用进度条时您可以依据自身需要重新实现该回调函数,以下仅为参考示例。
static void ProgressCallback(std::shared_ptr<DataTransferStatus> datatransferstatus) {
    int64_t consumedBytes = datatransferstatus->consumedBytes_;
    int64_t totalBytes = datatransferstatus->totalBytes_;
    int64_t rwOnceBytes = datatransferstatus->rwOnceBytes_;
    DataTransferType type = datatransferstatus->type_;
    int64_t rate = 100 * consumedBytes / totalBytes;
    std::cout << "rate:" << rate << ","
              << "ConsumedBytes:" << consumedBytes << ","
              << "totalBytes:" << totalBytes << ","
              << "rwOnceBytes:" << rwOnceBytes << ","
              << "DataTransferType:" << type << std::endl;
}

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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    // 需要上传的对象数据,以 stringstream 的形式上传
    std::string data("Object data to be uploaded");
    auto ss = std::make_shared<std::stringstream>(data);
    PutObjectV2Input input(bucketName, objectName, ss);
    
    // 设置进度条,DataTransferListener 参数用于实现进度条功能,用户可根据需要自定义 ProgressCallback
    DataTransferListener datatransferlistener = {ProgressCallback, nullptr};
    input.setDataTransferListener(datatransferlistener);
    
    auto output = client.putObject(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObjectWithProcess failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObjectWithProcess success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

配置客户端限速

以下代码用于在普通上传时设置客户端限速。

#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 名称,例如 examplebucket
    std::string bucketName = "examplebucket";
    // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
    std::string objectName = "exampledir/exampleobject.txt";
    
    // 初始化网络等资源
    InitializeClient();
    // 创建交互的 client
    TosClientV2 client(region, accessKey, secretKey);
    
    // 需要上传的对象数据,以 stringstream 的形式上传
    std::string data("1234567890abcdefghijklmnopqrstuvwxyz");
    auto ss = std::make_shared<std::stringstream>(data);
    PutObjectV2Input input(bucketName, objectName, ss);
    
    // 设置客户端限速,RateLimiter 参数用于实现进度条功能,用户可根据需要自定义  
    // TOS C++ SDK 通过最基本的令牌桶算法实现了客户端限速,其中第一个传入参数为总容量,第二个传入参数为生成令牌的速率
    // 以下配置的意义为 5mb/s 的平均上传速率,令牌桶总容量为 10 mb
    std::shared_ptr<RateLimiter> RateLimiter(NewRateLimiter(10 * 1024 * 1024, 5 * 1024 * 1024));
    input.setRateLimiter(RateLimiter);
    
    auto output = client.putObject(input);
    if (!output.isSuccess()) {
        // 异常处理
        std::cout << "PutObjectWithRateLimiter failed." << output.error().String() << std::endl;
        // 释放网络等资源
        CloseClient();
        return -1;
    }
    std::cout << "PutObjectWithRateLimiter success. the object etag:" << output.result().getETag() << std::endl;

    // 释放网络等资源
    CloseClient();
    return 0;
}

相关文档

关于上传对象的 API 文档,请参见 PutObject