本文介绍如何使用断点续传上传。

在无线网络下,上传比较大的文件持续时间长,可能会遇到因为网络条件差、用户切换网络等原因导致上传中途失败,整个文件需要重新上传。为此,SDK提供了断点续传上传功能。

注意
  • 断点续传上传暂时只支持上传本地文件。
  • 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传上传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。

通过断点续传上传的方式将文件上传到OSS前,您可以指定断点记录的保存文件夹。

  • 断点续传上传只在本次上传生效。如果未指定断点记录的保存文件夹,假设某个分片因为网络原因等导致文件上传失败时,将耗用大量的重试时间及流量来重新上传整个大文件。
  • 如果指定了断点记录的保存文件夹,在文件上传失败时,将从断点记录处继续上传未上传完成的部分。

断点续传上传时如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。此时,您可以通过为Bucket设置lifeCycle规则的方式来定时清理碎片。详情请参考:生命周期管理

出于碎片管理的原因,如果在断点续传时取消当前上传任务,默认会同步清理已经上传到服务器的分片。取消上传任务时如果仍希望保留断点上传记录,则需要指定断点记录的保存文件夹并修改deleteUploadIdOnCancelling参数。如果本地保留记录时间过长,且Bucket已设置lifeCycle规则定时清理了服务端分片,会出现服务端和移动端记录不一致的问题。

说明
  • 断点续传上传需要依赖InitMultipartUploadUploadPartListPartsCompleteMultipartUploadAbortMultipartUpload这些接口来实现。如果您需要通过STS鉴权模式来使用断点续传上传,则需要保证您拥有访问上述API接口的权限。
  • 断点续传上传也支持上传后回调通知,使用用法与常见的上传回调通知一致。
  • 断点续传上传默认已开启每个分片上传时的MD5校验,因此无需在request中设置Content-Md5头部。
  • 在本地持久保存断点记录的调用方式:
    OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
    resumableUpload.bucketName = OSS_BUCKET_PRIVATE;
    //...
    NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    resumableUpload.recordDirectoryPath = cachesDir;
    				
    说明 使用断点续传上传文件失败时会生成断点记录文件,然后从断点记录处继续上传直到上传完成。上传成功后会自动删除断点记录文件,默认情况下不会在本地持久保存断点记录。
  • 以下代码用于实现断点续传上传:
    // 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象
    OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
    resumableUpload.bucketName = <bucketName>;
    resumableUpload.objectKey = <objectKey>;
    resumableUpload.partSize = 1024 * 1024;
    resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
        NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
    };
    NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    //设置断点记录文件
    resumableUpload.recordDirectoryPath = cachesDir;
    //设置NO,取消时,不删除断点记录文件,如果不进行设置,默认YES,是会删除断点记录文件,下次再进行上传时会重新上传。
    resumableUpload.deleteUploadIdOnCancelling = NO;
    
    resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
    OSSTask * resumeTask = [client resumableUpload:resumableUpload];
    [resumeTask continueWithBlock:^id(OSSTask *task) {
        if (task.error) {
            NSLog(@"error: %@", task.error);
            if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {
                // 该任务无法续传,需要获取新的uploadId重新上传
            }
        } else {
            NSLog(@"Upload file success");
        }
        return nil;
    }];
    
    // [resumeTask waitUntilFinished];
    
    // [resumableUpload cancel];