当下载大对象时,可能出现网络波动等情况导致下载对象失败,TOS C++ SDK 提供了重试机制保障下载对象的稳定性,但可能出现多次重试后仍无法完成下载的情况。针对上述情况,TOS C++ SDK 提供了断点续传下载的功能,借助本地 CheckPoint 的机制记录已下载成功的分片。当出现网络异常或机器故障等问题导致下载中断,可再次调用该接口以实现续传的效果。
断点续传下载将待下载的对象分割为多个分片,并支持并发下载,待所有分片下载完成后,合并成完整的文件。您可以设置断点续传下载的分片大小、下载分片的线程数、下载时客户端限速、事件回调函数等。同时也能在断点续传下载任务执行过程中,取消该任务。
tos:GetObject
权限,具体操作,请参见权限配置指南。tos:GetObjectVersion
权限,具体操作,请参见权限配置指南。Checkpoint
文件中,所以程序需要对 Checkpoint
文件有写权限。Checkpoint
文件中,如果下载过程中某一分片下载失败,再次下载时会从 Checkpoint
文件中记录的点继续下载,从而达到断点续传的效果。下载完成后, Checkpoint
文件会被删除。以下代码用于断点续传下载桶 examplebucket
中的对象 exampledir/exampleobject.txt
到本地文件中,以及失败后重新下载。若上传过程中返回网络超时的报错,则您可以以相同参数调用 downloadFile 后实现断点续传下载重入。
#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"; // 下载Object到本地文件examplefile.txt,并保存到指定的本地路径中,例如/localpath/examplefile.txt,如果指定的本地文件存在会覆盖,不存在则新建。 std::string filePath = "/localpath/examplefile.txt"; // 记录断点记录文件的完整路径。只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。 // 如果未设置该值,默认与待上传的本地文件同路径。 std::string CheckpointFilePath = "yourCheckpointFilepath"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); // 断点续传下载 DownloadFileInput input(bucketName, objectName); // 并发下载分片的线程数 1-1000 input.setTaskNum(10); // 开启 checkpoint 会在本地生成断点续传记录文件 input.setEnableCheckpoint(true); // 默认分片大小 20MB input.setPartSize(20 * 1024 * 1024); // 下载后文件的保存路径,不可为空,不可为文件夹,建议设置绝对路径 input.setFilePath(filePath); auto output = client.downloadFile(input); if (!output.isSuccess()) { // 异常处理 std::cout << "DownloadFile failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "DownloadFile success. object etag is: " << output.result().getHeadObjectV2Output().getETags() << 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"; // 下载Object到本地文件examplefile.txt,并保存到指定的本地路径中,例如/localpath/examplefile.txt,如果指定的本地文件存在会覆盖,不存在则新建。 std::string filePath = "/localpath/examplefile.txt"; // 记录断点记录文件的完整路径。只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。 // 如果未设置该值,默认与待上传的本地文件同路径。 std::string CheckpointFilePath = "yourCheckpointFilepath"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); // 断点续传下载 DownloadFileInput input(bucketName, objectName); // 并发下载分片的线程数 1-1000 input.setTaskNum(10); // 开启 checkpoint 会在本地生成断点续传记录文件 input.setEnableCheckpoint(true); // 默认分片大小 20MB input.setPartSize(20 * 1024 * 1024); // 下载后文件的保存路径,不可为空,不可为文件夹,建议设置绝对路径 input.setFilePath(filePath); // 设置进度条 DataTransferListener processHandler = {ProgressCallback, nullptr}; input.setDataTransferListener(processHandler); auto output = client.downloadFile(input); if (!output.isSuccess()) { // 异常处理 std::cout << "DownloadFile failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "DownloadFile success. object etag is: " << output.result().getHeadObjectV2Output().getETags() << std::endl; // 释放网络等资源 CloseClient(); return 0; }
downloadFile 接口调用过程会发送创建临时文件、下载分片、重命名临时文件等事件,您可以传入自定义接口来监听下载的相关事件,并实现自定义的业务逻辑。
以下代码用于自定义断点续传下载回调函数。
#include "TosClientV2.h" using namespace VolcengineTos; static void DownloadCallBack(std::shared_ptr<DownloadEvent> event) { DownloadEventType type_ = event->type_; bool error_ = event->error_; std::string bucket_ = event->bucket_; std::string key_ = event->key_; std::string versionId_ = event->versionId_; std::string filePath_ = event->filePath_; std::string fileInfo = bucket_ + key_ + versionId_ + filePath_; std::shared_ptr<std::string> checkpointFile_ = event->checkpointFile_; std::shared_ptr<std::string> tempFilePath_ = event->tempFilePath_; std::shared_ptr<DownloadPartInfo> downloadPartInfo_ = event->downloadPartInfo_; std::string downloadPartInfo = ""; if (downloadPartInfo_ != nullptr) { downloadPartInfo = std::to_string(downloadPartInfo_->rangeStart_) + "," + std::to_string(downloadPartInfo_->rangeEnd_) + "," + std::to_string(downloadPartInfo_->partNumber_); } std::cout << "type:" << type_ << "," << "error:" << error_ << "," << "fileInfo:" << fileInfo << "," << "checkpointFile:" << *checkpointFile_ << "," << "tempFilePath:" << *tempFilePath_ << "," << "downloadPartInfo:" << downloadPartInfo << 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"; // 下载Object到本地文件examplefile.txt,并保存到指定的本地路径中,例如/localpath/examplefile.txt,如果指定的本地文件存在会覆盖,不存在则新建。 std::string filePath = "/localpath/examplefile.txt"; // 记录断点记录文件的完整路径。只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。 // 如果未设置该值,默认与待上传的本地文件同路径。 std::string CheckpointFilePath = "yourCheckpointFilepath"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); // 断点续传下载 DownloadFileInput input(bucketName, objectName); // 并发下载分片的线程数 1-1000 input.setTaskNum(10); // 开启 checkpoint 会在本地生成断点续传记录文件 input.setEnableCheckpoint(true); // 默认分片大小 20MB input.setPartSize(20 * 1024 * 1024); // 下载后文件的保存路径,不可为空,不可为文件夹,建议设置绝对路径 input.setFilePath(filePath); // 设置 DownloadEvent DownloadEventListener downloadHandler = {DownloadCallBack}; input.setDownloadEventListener(downloadHandler); auto output = client.downloadFile(input); if (!output.isSuccess()) { // 异常处理 std::cout << "DownloadFile failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "DownloadFile success. object etag is: " << output.result().getHeadObjectV2Output().getETags() << 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"; // 下载Object到本地文件examplefile.txt,并保存到指定的本地路径中,例如/localpath/examplefile.txt,如果指定的本地文件存在会覆盖,不存在则新建。 std::string filePath = "/localpath/examplefile.txt"; // 记录断点记录文件的完整路径。只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。 // 如果未设置该值,默认与待上传的本地文件同路径。 std::string CheckpointFilePath = "yourCheckpointFilepath"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); // 断点续传下载 DownloadFileInput input(bucketName, objectName); // 并发下载分片的线程数 1-1000 input.setTaskNum(10); // 开启 checkpoint 会在本地生成断点续传记录文件 input.setEnableCheckpoint(true); // 默认分片大小 20MB input.setPartSize(20 * 1024 * 1024); // 下载后文件的保存路径,不可为空,不可为文件夹,建议设置绝对路径 input.setFilePath(filePath); // 设置 rateLimiter std::shared_ptr<RateLimiter> RateLimiter(NewRateLimiter(20 * 1024 * 1024, 5 * 1024 * 1024)); input.setRateLimiter(RateLimiter); auto output = client.downloadFile(input); if (!output.isSuccess()) { // 异常处理 std::cout << "DownloadFile failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "DownloadFile success. object etag is: " << output.result().getHeadObjectV2Output().getETags() << std::endl; // 释放网络等资源 CloseClient(); return 0; }
downloadFile 接口支持您主动暂停或取消断点续传任务。暂停断点续传任务会停止下载,再次调用 downloadFile 时可以从上次暂停的位置继续下载。取消断点续传任务会停止下载,删除本地的 CheckPoint 文件和下载的临时文件,再次调用 downloadFile 时会重新开始上传。
以下代码展示如何暂停或取消断点续传。
#include "TosClientV2.h" #include <thread> using namespace VolcengineTos; static void threadFunction1(TosClientV2 client, DownloadFileInput input) { auto output = client.downloadFile(input); if (!output.isSuccess()) { std::cout << "DownloadFile failed." << output.error().String() << std::endl; } std::cout << "DownloadFile success. object etag is: " << output.result().getHeadObjectV2Output().getETags() << std::endl; } static void threadFunction2(std::shared_ptr<CancelHook> CancelHook) { // false 代表不清除 checkpoint 等信息。true 代表清除 checkpoint 等信息 CancelHook->Cancel(false); } 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"; // 下载Object到本地文件examplefile.txt,并保存到指定的本地路径中,例如/localpath/examplefile.txt,如果指定的本地文件存在会覆盖,不存在则新建。 std::string filePath = "/localpath/examplefile.txt"; // 记录断点记录文件的完整路径。只有当Object下载中断产生了断点记录文件后,如果需要继续下载该Object,才需要设置对应的断点记录文件。下载完成后,该文件会被删除。 // 如果未设置该值,默认与待上传的本地文件同路径。 std::string CheckpointFilePath = "yourCheckpointFilepath"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); // 断点续传下载 DownloadFileInput input(bucketName, objectName); // 并发下载分片的线程数 1-1000 input.setTaskNum(10); // 开启 checkpoint 会在本地生成断点续传记录文件 input.setEnableCheckpoint(true); // 默认分片大小 20MB input.setPartSize(20 * 1024 * 1024); // 下载后文件的保存路径,不可为空,不可为文件夹,建议设置绝对路径 input.setFilePath(filePath); // 设置 cancelHook std::shared_ptr<CancelHook> CancelHook(NewCancelHook()); input.setCancelHook(CancelHook); // 线程1中执行断点续传下载接口 std::thread thread1(threadFunction1, client, input); thread1.detach(); TimeUtils::sleepSecondTimes(5); // 运行五秒后在线程2中中断该次请求 std::thread thread2(threadFunction2, CancelHook); thread1.join(); thread2.join(); // 释放网络等资源 CloseClient(); return 0; }