預設情況下,如果新添加檔案(Object)與現有檔案同名且對該檔案有存取權限,則新添加的檔案將覆蓋原有的檔案。本文介紹如何通過佈建要求頭x-oss-forbid-overwrite在簡單上傳、拷貝檔案及分區上傳等情境中禁止覆蓋同名檔案。
注意事項
使用本文樣本前您需要先通過自訂網域名、STS等方式建立OSSClient,具體請參見初始化。
簡單上傳
以下代碼用於簡單上傳時禁止覆蓋同名檔案:
OSSPutObjectRequest * put = [OSSPutObjectRequest new];
// 填寫Bucket名稱,例如examplebucket。關於Bucket名稱命名規範的更多資訊,請參見Bucket。
put.bucketName = @"examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。關於Object名稱命名規範的更多資訊,請參見Object。
put.objectKey = @"exampledir/exampleobject.txt";
// 填寫待上傳的本地檔案所在的完整路徑。
put.uploadingFileURL = [NSURL fileURLWithPath:@"/storage/emulated/0/oss/examplefile.txt"];
// 指定上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
put.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
// (可選)設定上傳進度。
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];
拷貝檔案
以下代碼用於拷貝檔案時禁止覆蓋同名檔案:
OSSCopyObjectRequest * copy = [OSSCopyObjectRequest new];
// 填寫源Bucket名稱。
copy.sourceBucketName = @"srcbucket";
// 填寫源Bucket內的Object完整路徑。
copy.sourceObjectKey = @"dir1/srcobject.txt";
// 填寫目標Bucket名稱。
copy.bucketName = @"destbucket";
// 填寫目標Bucket內的Object完整路徑。
copy.objectKey = @"dir2/destobject.txt";
// 指定上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
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];
分區上傳
以下代碼用於分區上傳時禁止覆蓋同名檔案:
__block NSString * uploadId = nil;
__block NSMutableArray * partInfos = [NSMutableArray new];
// 填寫Bucket名稱,例如examplebucket。
NSString * uploadToBucket = @"examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。
NSString * uploadObjectkey = @"exampledir/exampleobject.txt";
OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;
// 指定上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
init.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};
// multipartUploadInit返回的結果中包含UploadId,UploadId是分區上傳的唯一標識。您可以根據該uploadId發起相關操作,例如取消分區上傳、查詢分區上傳等。
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;
}
// 填寫待上傳的本地檔案所在的完整路徑。
NSString * filePath = @"/storage/emulated/0/oss/examplefile.txt";
// 擷取待上傳檔案的大小。
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize];
// 設定分區號,從1開始標識。每一個上傳的Part都有一個分區號,取值範圍是1~10000。
int chuckCount = *;
// 設定分區大小,單位為位元組,取值範圍為100 KB~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;
// 指定完成分區上傳操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
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];
相關文檔
關於簡單上傳的API介面說明,請參見PutObject。
關於拷貝檔案的API介面說明,請參見CopyObject。
分區上傳的完整實現涉及三個API介面,詳情如下:
關於初始化分區上傳事件的API介面說明,請參見InitiateMultipartUpload。
關於分區上傳Part的API介面說明,請參見UploadPart。
關於完成分區上傳的API介面說明,請參見CompleteMultipartUpload。
關於初始化OSSClient,請參見如何初始化OSSClient執行個體。