By default, if you upload an object whose key matches an existing object you have access to, OSS overwrites the existing object. Set the x-oss-forbid-overwrite request header to true to block overwrites during simple upload, copy object, and multipart upload operations.
Prerequisites
Before you begin, ensure that you have:
An OSSClient instance initialized using a custom domain name, Security Token Service (STS), or another method. See Initialization (iOS SDK)
How x-oss-forbid-overwrite works
All three examples in this topic set x-oss-forbid-overwrite in a metadata dictionary. The following table summarizes how each value affects the operation:
| Value | Behavior |
|---|---|
| Not set | Overwrites an existing object with the same key (default) |
false | Overwrites an existing object with the same key |
true | Fails with an error if an object with the same key already exists |
Simple upload
The following example prevents an object from being overwritten during a simple upload:
OSSPutObjectRequest *put = [OSSPutObjectRequest new];
// Specify the bucket name. Example: examplebucket.
put.bucketName = @"examplebucket";
// Specify the full object key, excluding the bucket name. Example: exampledir/exampleobject.txt.
put.objectKey = @"exampledir/exampleobject.txt";
// Specify the full path of the local file to upload.
put.uploadingFileURL = [NSURL fileURLWithPath:@"/storage/emulated/0/oss/examplefile.txt"];
// Fail the upload if an object with the same key already exists.
put.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
// Optional: track upload progress.
put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
OSSTask *putTask = [client putObject:put];
[putTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"upload object success!");
} else {
NSLog(@"upload object failed, error: %@", task.error);
}
return nil;
}];
// [putTask waitUntilFinished];Copy an object
The following example prevents an object from being overwritten when copying an object:
OSSCopyObjectRequest *copy = [OSSCopyObjectRequest new];
// Specify the source bucket name.
copy.sourceBucketName = @"srcbucket";
// Specify the full key of the source object.
copy.sourceObjectKey = @"dir1/srcobject.txt";
// Specify the destination bucket name.
copy.bucketName = @"destbucket";
// Specify the full key of the destination object.
copy.objectKey = @"dir2/destobject.txt";
// Fail the copy if an object with the same key already exists in the destination bucket.
copy.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
OSSTask *task = [client copyObject:copy];
[task continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"copy object success!");
} else {
NSLog(@"copy object failed, error: %@", task.error);
}
return nil;
}];
// [putTask waitUntilFinished];Multipart upload
For multipart upload, set x-oss-forbid-overwrite in both the initiation request (init.objectMeta) and the complete request (complete.completeMetaHeader).
The following example prevents an object from being overwritten during a multipart upload:
__block NSString *uploadId = nil;
__block NSMutableArray *partInfos = [NSMutableArray new];
// Specify the bucket name. Example: examplebucket.
NSString *uploadToBucket = @"examplebucket";
// Specify the full object key, excluding the bucket name. Example: exampledir/exampleobject.txt.
NSString *uploadObjectkey = @"exampledir/exampleobject.txt";
// Initiate the multipart upload.
OSSInitMultipartUploadRequest *init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;
// Fail the upload if an object with the same key already exists.
init.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
// The upload ID uniquely identifies this multipart upload task. Use it to upload parts, cancel, or query the task.
OSSTask *initTask = [client multipartUploadInit:init];
[initTask waitUntilFinished];
if (!initTask.error) {
OSSInitMultipartUploadResult *result = initTask.result;
uploadId = result.uploadId;
} else {
NSLog(@"multipart upload failed, error: %@", initTask.error);
return;
}
// Upload parts.
// Specify the full path of the local file to upload.
NSString *filePath = @"/storage/emulated/0/oss/examplefile.txt";
// Get the file size.
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize];
// Part numbers start from 1 and range from 1 to 10,000.
int chuckCount = *;
// Part size ranges from 100 KB to 5 GB.
uint64_t offset = fileSize / chuckCount;
for (int i = 1; i <= chuckCount; i++) {
OSSUploadPartRequest *uploadPart = [OSSUploadPartRequest new];
uploadPart.bucketName = uploadToBucket;
uploadPart.objectkey = uploadObjectkey;
uploadPart.uploadId = uploadId;
uploadPart.partNumber = i; // part number start from 1
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
[readHandle seekToFileOffset:offset * (i - 1)];
NSData *data = [readHandle readDataOfLength:offset];
uploadPart.uploadPartData = data;
OSSTask *uploadPartTask = [client uploadPart:uploadPart];
[uploadPartTask waitUntilFinished];
if (!uploadPartTask.error) {
OSSUploadPartResult *result = uploadPartTask.result;
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteString error:nil] fileSize];
[partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTag size:fileSize]];
} else {
NSLog(@"upload part error: %@", uploadPartTask.error);
return;
}
}
// Complete the multipart upload.
OSSCompleteMultipartUploadRequest *complete = [OSSCompleteMultipartUploadRequest new];
complete.bucketName = uploadToBucket;
complete.objectKey = uploadObjectkey;
complete.uploadId = uploadId;
complete.partInfos = partInfos;
// Fail the upload if an object with the same key already exists.
complete.completeMetaHeader = @{@"x-oss-forbid-overwrite": @"true"};
OSSTask *completeTask = [client completeMultipartUpload:complete];
[[completeTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"multipart upload success!");
} else {
NSLog(@"multipart upload error: %@", task.error);
}
return nil;
}] waitUntilFinished];What's next
PutObject — API reference for simple upload
CopyObject — API reference for copying objects
InitiateMultipartUpload — API reference for initiating a multipart upload
UploadPart — API reference for uploading a part
CompleteMultipartUpload — API reference for completing a multipart upload