All Products
Search
Document Center

Object Storage Service:Prevent overwrites of objects with same names by using OSS SDK for iOS

Last Updated:Aug 27, 2024

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.

Usage notes

  • Before you run the sample code in this topic, you must create an OSSClient instance by using methods such as using a custom domain name or Security Token Service (STS). For more information, see Initialization.

Prevent overwrites in a simple upload task

The following sample 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 bucket naming, see Bucket naming conventions. 
put.bucketName = @"examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path. 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 an existing object with the same name. 
// If x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, an error is reported. 
put.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};

// (Optional) Configure an upload progress indicator. 
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 that you want to upload. 
    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;
}];
// Implement synchronous blocking to wait for the task to complete. 
// [putTask waitUntilFinished];

Prevent overwrites in an object copy task

The following sample code provides an example on how to prevent an existing object in a bucket from being overwritten by an object that has the same name in an object copy task:

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

// Specify whether to overwrite an existing object with the same name. 
// If x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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;
}];
// Implement synchronous blocking to wait for the task to complete. 
// [putTask waitUntilFinished];

Prevent overwrites in a multipart upload task

The following sample code provides an example on how to prevent objects from being overwritten by 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. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
NSString * uploadObjectkey = @"exampledir/exampleobject.txt";
OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;

// Specify whether to overwrite an existing object with the same name. 
// If x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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 perform related operations, such as canceling and querying 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 has a part number. Valid values: 1 to 10000. 
int chuckCount = *;
// Specify the size of each part. Unit: bytes. The valid 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;
    }
}

OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];
complete.bucketName = uploadToBucket;
complete.objectKey = uploadObjectkey;
complete.uploadId = uploadId;
complete.partInfos = partInfos;
// Specify whether to overwrite an object with the same name when you complete the multipart upload. 
// If x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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.

  • A multipart upload involves three API operations. For more information about the operations, see the following topics:

  • For more information about how to initialize an OSSClient instance, see Initialization.