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

断点续传

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

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

在上传前,可以指定断点记录的保存文件夹。若不进行此项设置,断点上传只在本次上传生效,某个分片因为网络原因等上传失败时会进行重试,避免整个大文件重新上传,节省重试时间和耗用流量。如果设置了断点记录的保存文件夹,如果任务失败,在下次重新启动任务,上传同一文件到同一Bucket、Object时,如果用户设置取消时不删除断点记录。再次上传将从断点记录处继续上传。详见随后的范例。

断点续传失败时,如果同一任务一直得不到续传,可能会在OSS上积累无用碎片。对这种情况,可以为Bucket设置lifeCycle规则,定时清理碎片。参考:生命周期管理

说明
  • 断点续传的实现依赖InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload,如果采用STS鉴权模式,请注意加上这些API所需的权限。
  • 断点续传也支持上传后回调通知,用法和上述普通上传回调通知一致。
  • 断点续传已经默认开启每个分片上传时的Md5校验,请勿重复在request中设置Content-Md5头部。
  • 不在本地持久保存断点记录的调用方式:
    // 创建断点上传请求
    ResumableUploadRequest request = new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
    // 设置上传过程回调
    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) {
    		// 异常处理
    	}
    });
    
    // resumableTask.waitUntilFinished(); // 可以等待直到任务完成
    
  • 在本地持久保存断点记录的调用方式:
    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) {
    		// 异常处理
    	}
    });
    
    // resumableTask.waitUntilFinished();
    
  • 断点续传功能实现:
    //调用OSSAsyncTask cancel()方法时是否需要删除断点记录文件的设置
    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);
    //设置false,取消时,不删除断点记录文件,如果不进行设置,默认true,是会删除断点记录文件,下次再进行上传时会重新上传。
    request.setDeleteUploadOnCancelling(false);
    // 设置上传过程回调
    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) {
    		// 异常处理
    	}
    });
    
    // resumableTask.waitUntilFinished();