默认情况下,如果新添加文件(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实例。
文档内容是否对您有帮助?