断点续传下载
当下载大对象到本地文件时,经常出现因网络不稳定或程序崩溃导致下载失败的情况。失败后再次重新下载不仅浪费资源,而且当网络不稳定时仍然有下载失败的风险。断点续传下载接口能有效地解决此类问题引起的下载失败,其原理是将待下载的对象分成若干个分段分别下载,并实时地将每段下载结果统一记录在checkpoint文件中,仅当所有分段都下载成功时返回下载成功的结果,否则抛出异常提醒用户再次调用接口进行重新下载(重新下载时因为有checkpoint文件记录当前的下载进度,避免重新下载所有分段,从而节省资源提高效率)。
您可以通过downloadFile进行断点续传下载。该接口可设置的参数如下:
参数 |
作用 |
OBS iOS SDK对应方法 |
---|---|---|
bucketName |
桶名,必选参数。 |
request.bucketName |
objectKey |
对象名,必选参数。 |
request.objectKey |
downloadFilePath |
下载对象的本地文件全路径。 |
request.downloadFilePath |
versionID |
对象的版本号。 |
request.versionID |
enableCheckpoint |
是否开启断点续传模式,默认为NO,表示不开启。 |
request.enableCheckpoint |
enableMD5Check |
是否开启MD5校验。 |
request.enableMD5Check |
enableForceOverwrite |
是否开启强制覆盖。 |
request.enableForceOverwrite |
checkpointFilePath |
记录下载进度的文件,只在断点续传模式下有效。当该值为空时,默认与下载对象的本地文件路径同目录。 |
request.checkpointFilePath |
partSize |
分段大小,单位字节,取值范围是5MB~5GB。 |
request.partSize |
ifModifiedSince |
如果对象在指定的时间后有修改,则返回对象内容,否则返回错误。。 |
request.ifModifiedSince |
ifUnmodifiedSince |
如果对象在指定的时间后没有修改,则返回对象内容,否则返回错误。 |
request.ifUnmodifiedSince |
ifETagMatch |
如果对象的ETag值与该参数值相同,则返回对象内容,否则抛出异常。 |
request.ifETagMatch |
ifETagNoneMatch |
如果对象的ETag值与该参数值不相同,则返回对象内容,否则抛出异常。 |
request.ifETagNoneMatch |
以下代码展示了如何使用断点续传下载接口下载对象到本地文件:
static OBSClient *client; NSString *endPoint = @"your-endpoint"; // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。 // 您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html char* ak_env = getenv("AccessKeyID"); char* sk_env = getenv("SecretAccessKey"); NSString *AK = [NSString stringWithUTF8String:ak_env]; NSString *SK = [NSString stringWithUTF8String:sk_env]; // 初始化身份验证 OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK]; //初始化服务配置 OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider]; // 初始化client client = [[OBSClient alloc] initWithConfiguration:conf]; // 存储路径 NSString * outfilePath = [NSTemporaryDirectory() stringByAppendingString:@"filename"]; // 最大并发数 self.client.configuration.maxConcurrentDownloadRequestCount = 5; // 断点续传下载 OBSDownloadFileRequest *request = [[OBSDownloadFileRequest alloc]initWithBucketName:@"bucketname" objectKey:@"objectname" downloadFilePath:outfilePath]; // 是否打开强制覆盖 request.enableForceOverwrite = YES; // 分段大小 request.partSize = [NSNumber numberWithInteger:5*1024*1024]; // 是否开启断点续传 request.enableCheckpoint = YES; request.downloadProgressBlock = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { NSLog(@"%0.1f%%",(float)floor(totalBytesWritten*10000/totalBytesExpectedToWrite)/100); }; OBSBFTask *task = [client downloadFile:request completionHandler:^(OBSDownloadFileResponse *response, NSError *error) { NSLog(@"%@",response); }]; [task waitUntilFinished]; if(task.error){ // 重新下载 }