Prevent overwriting files with the same name (C++ SDK)
By default, uploading an object whose key already exists in a bucket silently overwrites the existing object. Set the x-oss-forbid-overwrite request header to true to make OSS reject the upload instead, protecting your existing data. This header is supported for simple upload, object copy (small and large files), and multipart upload.
Usage notes
The examples in this topic use the public endpoint for the China (Hangzhou) region. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint. For endpoint details, see Regions and endpoints.
The examples create an
OssClientinstance using an OSS endpoint. To create anOssClientwith a custom domain name or Security Token Service (STS), see Create an OSSClient instance.
How x-oss-forbid-overwrite works
All three upload and copy operations accept x-oss-forbid-overwrite in the request metadata. The header behavior is the same across operations:
x-oss-forbid-overwrite value | Result |
|---|---|
| Not set (default) | Existing object with the same name is overwritten |
false | Existing object with the same name is overwritten |
true | Upload is rejected; OSS returns an error if an object with the same name exists |
For multipart upload and large-file copy, set the header in both the InitiateMultipartUpload metadata and the CompleteMultipartUpload metadata.
Simple upload
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* Set the endpoint of the region where the bucket is located.
For the China (Hangzhou) region: https://oss-cn-hangzhou.aliyuncs.com */
std::string Endpoint = "yourEndpoint";
/* Set the region where the bucket is located. For China (Hangzhou): cn-hangzhou */
std::string Region = "yourRegion";
/* Bucket name. Example: examplebucket */
std::string BucketName = "examplebucket";
/* Full object path, excluding the bucket name. Example: exampledir/exampleobject.txt */
std::string ObjectName = "exampledir/exampleobject.txt";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* Read credentials from environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET. */
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
*content << "test cpp sdk";
/* Reject the upload if an object with the same name already exists. */
ObjectMetaData meta;
meta.addHeader("x-oss-forbid-overwrite", "true");
PutObjectRequest request(BucketName, ObjectName, content, meta);
auto outcome = client.PutObject(request);
if (!outcome.isSuccess()) {
std::cout << "PutObject fail"
<< ",code:" << outcome.error().Code()
<< ",message:" << outcome.error().Message()
<< ",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
ShutdownSdk();
return 0;
}Copy objects
Copy a small object
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
/* Source bucket name. Example: srcexamplebucket */
std::string SourceBucketName = "srcexamplebucket";
/* Destination bucket name (must be in the same region). Example: destbucket */
std::string CopyBucketName = "destbucket";
/* Full path of the source object, excluding the bucket name. Example: srcdir/scrobject.txt */
std::string SourceObjectName = "srcdir/scrobject.txt";
/* Full path of the destination object, excluding the bucket name. Example: destdir/destobject.txt */
std::string CopyObjectName = "destdir/destobject.txt";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
/* Reject the copy if a destination object with the same name already exists. */
ObjectMetaData meta;
meta.addHeader("x-oss-forbid-overwrite", "true");
CopyObjectRequest request(CopyBucketName, CopyObjectName, meta);
request.setCopySource(SourceBucketName, SourceObjectName);
auto outcome = client.CopyObject(request);
if (!outcome.isSuccess()) {
std::cout << "CopyObject fail"
<< ",code:" << outcome.error().Code()
<< ",message:" << outcome.error().Message()
<< ",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
ShutdownSdk();
return 0;
}Copy a large object
Large-object copy uses multipart copy (InitiateMultipartUpload + UploadPartCopy + CompleteMultipartUpload). Set x-oss-forbid-overwrite: true in both the initiate and complete requests.
#include <alibabacloud/oss/OssClient.h>
#include <sstream>
using namespace AlibabaCloud::OSS;
int main(void)
{
std::string Endpoint = "yourEndpoint";
std::string Region = "yourRegion";
std::string SourceBucketName = "srcexamplebucket";
std::string CopyBucketName = "destbucket";
std::string SourceObjectName = "srcdir/scrobject.txt";
std::string CopyObjectName = "destdir/destobject.txt";
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
/* Get the source object size. */
auto getObjectMetaReq = GetObjectMetaRequest(SourceBucketName, SourceObjectName);
auto getObjectMetaResult = client.GetObjectMeta(getObjectMetaReq);
if (!getObjectMetaResult.isSuccess()) {
std::cout << "GetObjectMeta fail"
<< ",code:" << getObjectMetaResult.error().Code()
<< ",message:" << getObjectMetaResult.error().Message()
<< ",requestId:" << getObjectMetaResult.error().RequestId() << std::endl;
return -1;
}
auto objectSize = getObjectMetaResult.result().ContentLength();
/* Set x-oss-forbid-overwrite in the InitiateMultipartUpload metadata. */
ObjectMetaData metaData;
std::stringstream ssDesc;
ssDesc << "/" << SourceBucketName << "/" << SourceObjectName;
std::string value = ssDesc.str();
metaData.addHeader("x-oss-copy-source", value);
metaData.addHeader("x-oss-forbid-overwrite", "true");
InitiateMultipartUploadRequest initUploadRequest(CopyBucketName, CopyObjectName, metaData);
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
int64_t partSize = 100 * 1024;
PartList partETagList;
int partCount = static_cast<int>(objectSize / partSize);
if (objectSize % partSize != 0) {
partCount++;
}
/* Copy each part. */
for (int i = 1; i <= partCount; i++) {
auto skipBytes = partSize * (i - 1);
auto size = (partSize < objectSize - skipBytes) ? partSize : (objectSize - skipBytes);
auto uploadPartCopyReq = UploadPartCopyRequest(CopyBucketName, CopyObjectName,
SourceBucketName, SourceObjectName, uploadId, i + 1);
uploadPartCopyReq.setCopySourceRange(skipBytes, skipBytes + size - 1);
auto uploadPartOutcome = client.UploadPartCopy(uploadPartCopyReq);
if (uploadPartOutcome.isSuccess()) {
Part part(i, uploadPartOutcome.result().ETag());
partETagList.push_back(part);
} else {
std::cout << "UploadPartCopy fail"
<< ",code:" << uploadPartOutcome.error().Code()
<< ",message:" << uploadPartOutcome.error().Message()
<< ",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
}
}
/* Set x-oss-forbid-overwrite again in the CompleteMultipartUpload request. */
CompleteMultipartUploadRequest request(CopyBucketName, CopyObjectName, partETagList, uploadId);
request.MetaData().addHeader("x-oss-forbid-overwrite", "true");
auto outcome = client.CompleteMultipartUpload(request);
if (!outcome.isSuccess()) {
std::cout << "CompleteMultipartUpload fail"
<< ",code:" << outcome.error().Code()
<< ",message:" << outcome.error().Message()
<< ",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
ShutdownSdk();
return 0;
}Multipart upload
Multipart upload (InitiateMultipartUpload + UploadPart + CompleteMultipartUpload) also requires x-oss-forbid-overwrite: true in both the initiate and complete requests.
#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)
{
std::string Endpoint = "yourEndpoint";
std::string BucketName = "examplebucket";
std::string ObjectName = "exampledir/exampleobject.txt";
InitializeSdk();
ClientConfiguration conf;
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
/* Set x-oss-forbid-overwrite in the InitiateMultipartUpload metadata. */
ObjectMetaData meta;
meta.addHeader("x-oss-forbid-overwrite", "true");
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName, meta);
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
std::string fileToUpload = "yourLocalFilename";
int64_t partSize = 100 * 1024;
PartList partETagList;
auto fileSize = getFileSize(fileToUpload);
int partCount = static_cast<int>(fileSize / partSize);
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;
}
}
/* Set x-oss-forbid-overwrite again in the CompleteMultipartUpload request. */
CompleteMultipartUploadRequest request(BucketName, ObjectName);
request.setUploadId(uploadId);
request.setPartList(partETagList);
request.MetaData().addHeader("x-oss-forbid-overwrite", "true");
auto outcome = client.CompleteMultipartUpload(request);
if (!outcome.isSuccess()) {
std::cout << "CompleteMultipartUpload fail"
<< ",code:" << outcome.error().Code()
<< ",message:" << outcome.error().Message()
<< ",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
ShutdownSdk();
return 0;
}