By default, if you upload an object that has the same name as an existing object on which you have access permissions, the existing object is overwritten by the uploaded object. This topic describes how to configure the x-oss-forbid-overwrite request header to prevent objects from being overwritten by objects with the same names when you copy objects or perform simple upload or multipart upload.

Simple upload

The following code provides an example on how to prevent objects from being overwritten by objects that have the same names in simple upload:

OSSPutObjectRequest * put = [OSSPutObjectRequest new];

// Specify the name of the bucket. Example: examplebucket. For more information about the naming conventions for buckets, see Bucket naming conventions. 
put.bucketName = @"examplebucket";
// Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. For more information about the naming conventions for objects, see Object naming conventions. 
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"];

// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
put.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};

// (Optional) Specify the upload progress. 
put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
    // Specify the number of bytes that are being uploaded, the total number of bytes that are uploaded, and the total number of bytes to be uploaded. 
    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;
}];

Copy objects

The following code provides an example on how to prevent existing objects from being overwritten by newly copied objects that have the same names:

OSSCopyObjectRequest * copy = [OSSCopyObjectRequest new];
// Specify the name of the source bucket. 
copy.sourceBucketName = @"srcbucket";
// Specify the full path of the object in the source bucket. 
copy.sourceObjectKey = @"dir1/srcobject.txt";
// Specify the name of the destination bucket. 
copy.bucketName = @"destbucket";
// Specify the full path of the object in the destination bucket. 
copy.objectKey = @"dir2/destobject.txt";

// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the copied object, an error is reported. 
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;
}];

Multipart upload

The following code provides an example on how to prevent objects from being overwritten by newly uploaded objects that have the same names in multipart upload:

__block NSString * uploadId = nil;
__block NSMutableArray * partInfos = [NSMutableArray new];
// Specify the name of the bucket. Example: examplebucket. 
NSString * uploadToBucket = @"examplebucket";
// Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. 
NSString * uploadObjectkey = @"exampledir/exampleobject.txt";
OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;

// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
init.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
// The response to multipartUploadInit contains the upload ID. The upload ID is the unique ID of the multipart upload task. You can use the upload ID to cancel or query the multipart upload 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;
}

// Specify the full path of the local file to upload. 
NSString * filePath = @"/storage/emulated/0/oss/examplefile.txt";
// Query the size of the file to upload. 
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize];
// Specify the part number for each part. The number starts from 1. Each part to upload has a part number. Valid values: 1 to 10000. 
int chuckCount = *;
// Specify the size of each part. Unit: bytes. Valid values: 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;
    }
}

OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];
complete.bucketName = uploadToBucket;
complete.objectKey = uploadObjectkey;
complete.uploadId = uploadId;
complete.partInfos = partInfos;
// Specify whether to overwrite the object with the same name when the multipart upload task is complete. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
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];

References

  • For more information about the API operation that you can call to perform simple upload, see PutObject.
  • For more information about the API operation that you can call to copy an object, see CopyObject.
  • The following API operations are required to perform multipart upload:
    • The API operation that you can call to initiate a multipart upload task. For more information, see InitiateMultipartUpload.
    • The API operation that you can call to upload data by part. For more information, see UploadPart.
    • The API operation that you can call to complete a multipart upload task. For more information, see CompleteMultipartUpload.