版本控制应用于桶中所有对象。通过开启桶的版本控制,您可以在错误删除或者覆盖对象后,将对象回恢复至任意的历史版本。
目前支持多版本的接口包含 GetObject、GetObjectACL、CopyObject、UploadPartCopy、DeleteObject等。调用相关接口时,您可通过可选参数 versionID 指定操作对象的具体版本。
TOS 中桶的版本状态包含未开启、开启版本控制和暂停版本控制三种,本文介绍桶的多版本管理。
tos:PutBucketVersioning
权限。tos:GetBucketVersioning
权限。以下代码用于设置桶状态为开启多版本(Enable)状态。
#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"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); PutBucketVersioningInput input(bucketName,VersioningStatusType::Enabled); auto output = client.putBucketVersioning(input); if (!output.isSuccess()) { // 异常处理 std::cout << "OpenBucketVersioning failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "OpenBucketVersioning success." << std::endl; // 释放网络等资源 CloseClient(); return 0; }
以下代码用于设置桶状态为暂停版本控制状态(Suspended)。
#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"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); PutBucketVersioningInput input(bucketName,VersioningStatusType::Suspended); auto output = client.putBucketVersioning(input); if (!output.isSuccess()) { // 异常处理 std::cout << "SuspendBucketVersioning failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "SuspendBucketVersioning success." << std::endl; // 释放网络等资源 CloseClient(); return 0; }
以下代码用于获取桶 examplebucket
的版本控制状态信息。
#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"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); GetBucketVersioningInput input(bucketName); auto output = client.getBucketVersioning(input); if (!output.isSuccess()) { // 异常处理 std::cout << "GetBucketVersioning failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "GetBucketVersioning success." << std::endl; std::cout << "versioning statue" << output.result().getStringFormatVersioningStatus() << 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"; // 填写对象的 versionId std::string versionId = "your object version"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); GetObjectV2Input input(bucketName, objectName); input.setVersionId(versionId); auto output = client.getObject(input); if (!output.isSuccess()) { // 异常处理 std::cout << "GetObject failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "GetObject success. the object etag:" << output.result().getETags() << 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"; // 填写对象的 versionId std::string versionId = "your object version"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); DeleteObjectInput input(bucketName,objectName); input.setVersionID(versionId); auto output = client.deleteObject(input); if (!output.isSuccess()) { // 异常处理 std::cout << "DeleteObject failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } std::cout << "DeleteObject success." << std::endl; std::cout << " version id is:" << output.result().getVersionId() << " is delete marker:" << output.result().isDeleteMarker() << 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"; // 初始化网络等资源 InitializeClient(); // 创建交互的 client TosClientV2 client(region, accessKey, secretKey); ListObjectVersionsV2Input input(bucketName); bool isTruncated = true; std::string nextKeyMarker = ""; std::string nextVersionIdMarker = ""; DeleteObjectInput deleteObjectInput; deleteObjectInput.setBucket(bucketName); while(isTruncated){ input.setKeyMarker(nextKeyMarker); input.setVersionIdMarker(nextVersionIdMarker); auto output = client.listObjectVersions(input); if (!output.isSuccess()) { // 异常处理 std::cout << "ListObjects failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } nextKeyMarker = output.result().getNextKeyMarker(); nextVersionIdMarker = output.result().getNextVersionIdMarker(); isTruncated = output.result().isTruncated(); for (const auto& versions : output.result().getVersions()) { deleteObjectInput.setKey(versions.getKey()); deleteObjectInput.setVersionID(versions.getVersionId()); auto deleteOutput = client.deleteObject(deleteObjectInput); if (!deleteOutput.isSuccess()){ if(output.error().getStatusCode() != 404 && output.error().getCode() != "NoSuchKey"){ std::cout << "DeleteObject failed:" << deleteOutput.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } } } for (const auto& deleteMarker : output.result().getDeleteMarkers()) { deleteObjectInput.setKey(deleteMarker.getKey()); deleteObjectInput.setVersionID(deleteMarker.getVersionId()); auto deleteOutput = client.deleteObject(deleteObjectInput); if (!deleteOutput.isSuccess()){ if(output.error().getStatusCode() != 404 && output.error().getCode() != "NoSuchKey"){ std::cout << "DeleteObject failed:" << deleteOutput.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } } } } // 列举已上传分片 ListMultipartUploadsV2Input input2(bucketName); AbortMultipartUploadInput abortMultipartUploadInput; abortMultipartUploadInput.setBucket(bucketName); // isTruncated用于控制是否列举完全,nextKeyMarker用于递归列举 isTruncated = true; nextKeyMarker = ""; while(isTruncated){ input2.setKeyMarker(nextKeyMarker); auto output = client.listMultipartUploads(input2); if (!output.isSuccess()) { // 异常处理 std::cout << "ListMultipartUploads failed." << output.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } nextKeyMarker = output.result().getNextKeyMarker(); isTruncated = output.result().isTruncated(); std::cout << "ListMultipartUploads success." << std::endl; for (const auto& part : output.result().getUploads()) { abortMultipartUploadInput.setKey(part.getKey()); abortMultipartUploadInput.setUploadId(part.getUploadId()); auto abortOutput = client.abortMultipartUpload(abortMultipartUploadInput); if (!abortOutput.isSuccess()){ std::cout << "DeletePart failed:" << abortOutput.error().String() << std::endl; // 释放网络等资源 CloseClient(); return -1; } } } // 释放网络等资源 CloseClient(); return 0; }