全部產品
Search
文件中心

Object Storage Service:iOS禁止覆蓋同名檔案

更新時間:Aug 27, 2024

預設情況下,如果新添加檔案(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];

相關文檔