多线程上传的好处android
在本地持久保存断点记录的调用方式:ios
android:api
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 要保证目录存在,若是不存在则主动建立
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立断点上传请求,参数中给出断点记录文件的保存位置,需是一个文件夹的绝对路径
ResumableUploadRequest request
= new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>", recordDirectory);
// 设置上传过程回调
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
@Override
public void onProgress(ResumableUploadRequest request
, long currentSize, long totalSize) {
Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
OSSAsyncTask resumableTask = oss.asyncResumableUpload(request
, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
@Override
public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
Log.d("resumableUpload", "success!");
}
@Override
public void onFailure(ResumableUploadRequest request, ClientException clientExcepion
, ServiceException serviceException) {
// 异常处理
}
});复制代码
ios:缓存
// 得到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);
};
resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
resumableUpload.recordDirectoryPath = cachesDir;//记录断点的文件路径
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;
}];复制代码
数据分析
android/ios 端的分片上传改成并发后的测试与以前对比,上传分片的网络请求速度 多线程 和 单线程是同样的使用时间,这个主要是取决于带宽速度, 多线程相较于单线程主要是提升了读取文件的io时间。数据以下:bash
iOS 模拟器测试
100mb大小文件
1000 part num 单线程 104.530217s 多线程 54.528591s
100 part num 单线程 59.306880s 多线程 54.336914s
1.31g 大小文件
100 part num 单线程 746.775666s 多线程 731.940330s
1000 part num 单线程 822.866331s 多线程 733.306236s
2000 part num 单线程 965.428122s 多线程 731.940330s
5000 part num 单线程 1205.379382s 多线程 732.982330s
android motoXT1085 双核cpu
100mb文件
100 part num 单线程 70.484s 多线程 53.656s
1000 part num 单线程 104.530217s 多线程54.528591s
1.31g视频文件
135 part num 单线程 869s 多线程 738s
1342 part num 单线程 1079.081s 多线程 732.079s复制代码
整体来看比以前有提高,单线程随着片的个数的增长时间耗时愈来愈高,而多线程下,时间基本是同样的,按照目前默认配置的part size 256kb ,单线程下网络资源与I/O资源都吃满,并发下性能提升平均有30%左右(上传时间减小)服务器
移动端下,网络资源与I/O资源通常都比较紧缺,多线程不会提升网络的总带宽:好比,在跑满某个资源下载策略分配一个链接供给带宽2000Kb/s的时候,本地单线程 可以同时吃满 2000Kb/s,这里就到达了一个峰值;可是若是某个资源链接带宽是2000Kb/s,可是单线程请求带宽 已经达到 2000Kb/s,那么就是本地网络带宽 Block了上传速度,也就是说开再多线程,再多链接也都无济于事;但,若是本地网络带宽 吃完2000Kb/s 的同时还有不少的网络资源剩余,假如还有2000Kb/s的提高空间,那么这时再创建一个链接 将这 2000Kb/s 也吃满,那么此时的速度就能够达到 4000Kb/s,这时提速很明显,I/O资源同理。网络