阿里云OSS对象存储上传文件(二)C++上传(含代码)

本文讲述了在阿里云OSS对象存储中,作者分享了在Windows环境下使用VS+Qt进行文件上传的实践经验,包括简单上传和分片上传的优缺点,以及如何实现进度条反馈。特别提到分片上传时的优化和潜在问题,如回调函数实现和中断后的文件管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为实际项目需求,需要使用阿里云oss的对象存储来上传文件。本篇将讲述个人代码使用上的经验,不代表适用所有人,仅供参考。
代码尝试前,请先确保SDK安装和lib文件编译等预备工作,详细可查看上一篇文章:
阿里云OSS对象存储上传文件(一)SDK安装

环境是windows系统,vs2017+qt5.14(vs2015+qt5.6也尝试过,效果都一样)
官方示例代码:官方文档:C++上传文件

一、核心需求
简单查看官方文档后,会发现它具备了好几种上传方法,包括简单上传,追加上传,断点续传上传,分片上传,等。因为我的项目核心需求是同时上传单个文件,所以过程中尝试了简单上传和分片上传,其他未做尝试,有兴趣可自行实现。
另一要求则是过程中需要给出进度条的ui提示,这需要获取oss的进度条反馈信息,这部分sdk也是有实现的。
以下先简单讲述以下简单上传和分片上传的优缺点。
(1)简单上传
即直接单次提交整个文件,只要不超过5GB即可。这种方法步骤比较简单,但同时没有办法实现中途中断功能(有人实现了可在评论区告知),并可能因为文件过大,而导致上传过程阻塞过久,往往可能一两分钟,又没办法停止,体验一般。
(2)分片上传
即把文件分成若干片段,分别上传。这种适合大文件的上传,最大不超过48.8TB。当然,几十MB大小的文件也同样可以上传,这个都没有问题。相较于简单上传,分片上传的灵活性显然提高了许多。如果想要实现停止上传,只要完成当前分片的上传把并退出上传循环即可。因为没有到最终的整合分片环节,所以云上的文件并不会最终生成(有没有缓存文件不知道)。
特别说明:
(1)值得一提的是,官方示例中的分片大小是100k,这会造成分片数量太过庞大,导致循环上传中各种初始化资源大量重复。比如上传一个100M的视频文件,用简单上传来整个文件上传,以及使用分片上传,按照100k分片,循环上传1000次,耗时上是有显著增加的。经过尝试,我认为控制在1M的分片会比较恰当,网络通畅的情况下几乎是瞬间上传完毕,不会造成明显的阻塞感。
(2)官方文档中有进度条回调的使用,但注意,不管是对简单上传还是分片上传,它的本质上都是对单次上传的进度条反抗,放在分片上传中,就是对单个切片的进度反馈,而不是一整个的。这在我实现分片上传中的进度条显示中遇到了困难。
a.初步的尝试,是利用切片的数量进行进度显示,即假如分片了100份,那当前上传到哪一片,自然就得到了当前的进度。当你知道的,切片不一定会超过100份,假如只有10份,那进度反馈将是跳跃式的,给人直观上不好。
b.最终的方案是,利用一开始对文件总大小的记录,以及当前上传切片编号,当前上传切片的进度反馈,自行实现数字累加,以达到真实的进度反馈。这部分比较繁琐,但也算是符合常理的。
OK,讲了这么多,接下来详细讲述以下代码。

二、简单上传

//进度条回调
void ProgressCallback(size_t increment, int64_t transfered, int64_t total, void* userData)
{
   
   
    std::cout << "ProgressCallback[" << userData << "] => " <<
                 increment <<" ," << transfered << "," << total << std::endl;
                 
	//alioosProgressCallback是我创建的全局回调对象,在这里间接地将进度信息发送到外部
    alioosProgressCallback.send_ProgressCallback(transfered, total);
}
//简单上传
bool AliossUpload::PutObjectFromFile()
{
   
   
	//根据自己实际情况,初始OSS账号信息
    /* 初始化OSS账号信息 */
    /* 如何获取AccessKeyId和AccessKeySecret:
    https://help.aliyun.com/knowledge_detail/48699.html
    */
    std::string AccessKeyId = _AccessKeyId.toStdString();
    std::string AccessKeySecret = _AccessKeySecret.toStdString();

    /* 根据文档填写所需Endpoint:
    https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.6.586.48977f5ev3c5Ht
    */
    std::string Endpoint = _Endpoint.toStdString();
    /* 填写你的存储空间名*/
    std::string BucketName = _BucketName.toStdString();
    /* ObjectName表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如image/bkg1.png文件 */
    std::string ObjectName = std::string(_ObjectName.toLocal8Bit());
    /* 本地文件实际路径,注意\要替换为/,不然中文路径会出问题 */
    std::string FilePathAndName = std::string(_FilePathAndName.toLocal8Bit());

    /* 初始化网络等资源 */
    InitializeSdk();

    /* 基本参数 */
    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(FilePathAndName, std::ios::in|std::ios::binary);
    PutObjectRequest request(BucketName, ObjectName, content);

    //进度回调
    TransferProgress progressCallback = {
   
    ProgressCallback , this };
    request.setTransferProgress(progressCallback);

    /* 上传文件 */
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值