下面演示通过分片上传文件的整个流程:
初始化分片上传
- __block NSString * uploadId = nil;
- __block NSMutableArray * partInfos = [NSMutableArray new];
- NSString * uploadToBucket = @"<bucketName>";
- NSString * uploadObjectkey = @"<objectKey>";
- OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
- init.bucketName = uploadToBucket;
- init.objectKey = uploadObjectkey;
- // init.contentType = @"application/octet-stream";
- 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;
- }
- OSSInitMultipartUploadRequest指定上传文件的所属存储空间Bucket和文件名字。
- multipartUploadInit发挥的结果中包含UploadId,是区分分片上传的唯一标示,后面的操作中会用到。
上传分片
- NSString * filePath = [docDir stringByAppendingPathComponent:@"***"];
- //要上传的文件
- int chuckCount = *;
- //分片上传数量
- uint64_t offset = fileSie/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;
- }
- }
上述代码调用uploadPart来上传每一个分片,注意:
- 每一个分片上传请求需指定UploadId和PartNum。
- uploadPart要求除最后一个Part外,其他的Part大小都要大于100KB。但是Upload Part接口并不会立即校验上传。Part的大小(因为不知道是否为最后一块);只有当Complete Multipart Upload的时候才会校验。
- Part号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。
- 每次上传part时都要把流定位到此次上传片开头所对应的位置。
- 每次上传part之后,OSS的返回结果会包含一个分片的ETag,值为part数据的MD5值,您需要将它和块编号组合成PartEtag保存,后续完成分片上传需要用到。
完成分片上传
下面代码中的 partInfos就是进行分片上传中保存的partETag的列表,OSS收到用户提交的Part列表后,会逐一验证每个数据Part的有效性。当所有的数据Part验证通过后,OSS会将这些part组合成一个完整的文件。
- OSSCompleteMultipartUploadRequest * complete = [OSSCompleteMultipartUploadRequest new];
- complete.bucketName = uploadToBucket;
- complete.objectKey = uploadObjectkey;
- complete.uploadId = uploadId;
- complete.partInfos = partInfos;
- OSSTask * completeTask = [client completeMultipartUpload:complete];
- [[completeTask continueWithBlock:^id(OSSTask *task) {
- if (!task.error) {
- OSSCompleteMultipartUploadResult * result = task.result;
- // ...
- } else {
- // ...
- }
- return nil;
- }] waitUntilFinished];