断点续传下载
当下载大文件时,如果网络不稳定或者程序崩溃了,则整个下载就失败了。用户不得不重头再来,这样做不仅浪费资源,在网络不稳定的情况下,往往重试多次还是无法完成下载。通过OSSClient.downloadFile接口来实现断点续传分片下载,参数是DownloadFileRequest,该请求有以下参数:
- bucket 存储空间名字,必选参数,通过构造方法设置
- key 下载到OSS的Object名字,必选参数,通过构造方法设置
- downloadFile 本地文件,下载到该文件,可选参数,默认是key,通过构造方法或setDownloadFile设置
- partSize 分片大小,从1B到5GB,单位是Byte,可选参数,默认100K,通过setPartSize设置
- taskNum 分片下载并发数,可选参数,默认为1,通过setTaskNum设置
- enableCheckpoint 下载是否开启断点续传,可选参数,默认断点续传功能关闭,通过setEnableCheckpoint设置
- checkpointFile 开启断点续传时,需要在本地记录分片下载结果,如果下载失败,下次不会再下载已经成功的分片,可选参数,默认与downloadFile同目录,为downloadFile.ucp,可以通过setCheckpointFile设置
其实现的原理是将要下载的Object分成若干个分片分别下载,最后所有分片都下载成功后,完成整个文件的下载。在下载的过程中会记录当前下载的进度信息(记录在checkpoint文件中)和已下载的分片,如果下载过程中某一分片下载失败,再次下载时会从checkpoint文件中记录的点继续下载。这要求再次调用时要指定与上次相同的checkpoint文件。下载完成后,checkpoint文件会被删除。
- // endpoint以杭州为例,其它region请按实际情况填写
- String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
- // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
- String accessKeyId = "<yourAccessKeyId>";
- String accessKeySecret = "<yourAccessKeySecret>";
- String bucketName = "<yourBucketName>";
- // 创建OSSClient实例
- OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
- // 下载请求,10个任务并发下载,启动断点续传
- DownloadFileRequest downloadFileRequest = new DownloadFileRequest("bucketName", "key");
- downloadFileRequest.setDownloadFile("downloadFile");
- downloadFileRequest.setTaskNum(10);
- downloadFileRequest.setEnableCheckpoint(true);
- // 下载文件
- DownloadFileResult downloadRes = ossClient.downloadFile(downloadFileRequest);
- // 下载成功时,会返回文件的元信息
- downloadRes.getObjectMetadata();
- // 关闭client
- ossClient.shutdown();
限定条件下载
下载文件时,可以指定一个或多个限定条件,满足限定条件时下载,不满足时报错,不下载文件。可以使用的限定条件如下:
注意:
- 如果If-Modified-Since设定的时间不符合规范,直接返回文件,并返回200 OK;
- If-Modified-Since和If-Unmodified-Since可以同时存在,If-Match和If-None-Match也可以同时存在;
- 如果包含If-Unmodified-Since并且不符合或者包含If-Match并且不符合,返回412 precondition failed;
- 如果包含If-Modified-Since并且不符合或者包含If-None-Match并且不符合,返回304 Not Modified。
- // endpoint以杭州为例,其它region请按实际情况填写
- String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
- // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
- String accessKeyId = "<yourAccessKeyId>";
- String accessKeySecret = "<yourAccessKeySecret>";
- String bucketName = "<yourBucketName>";
- // 创建OSSClient实例
- OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
- GetObjectRequest request = new GetObjectRequest(bucketName, "<yourKey>");
- request.setModifiedSinceConstraint(new Date());
- // 下载object到文件
- ossClient.getObject(request, new File("<yourLocalFile>"));
- // 关闭client
- ossClient.shutdown();
提示:
- ETag的值可以通过OSSClient.getObjectMetadata获取;
- OSSClient.getObject,OSSClient.downloadFile都支持限定条件。
下载进度条
OSS Java sdk支持进度条功能,指示上传/下载的进度。下面的代码以OSSClient.getObject为例,说明进度条功能的使用。
提示:
- static class GetObjectProgressListener implements ProgressListener {
- private long bytesRead = 0;
- private long totalBytes = -1;
- private boolean succeed = false;
- @Override
- public void progressChanged(ProgressEvent progressEvent) {
- long bytes = progressEvent.getBytes();
- ProgressEventType eventType = progressEvent.getEventType();
- switch (eventType) {
- case TRANSFER_STARTED_EVENT:
- System.out.println("Start to download......");
- break;
- case RESPONSE_CONTENT_LENGTH_EVENT:
- this.totalBytes = bytes;
- System.out.println(this.totalBytes + " bytes in total will be downloaded to a local file");
- break;
- case RESPONSE_BYTE_TRANSFER_EVENT:
- this.bytesRead += bytes;
- if (this.totalBytes != -1) {
- int percent = (int)(this.bytesRead * 100.0 / this.totalBytes);
- System.out.println(bytes + " bytes have been read at this time, download progress: " +
- percent + "%(" + this.bytesRead + "/" + this.totalBytes + ")");
- } else {
- System.out.println(bytes + " bytes have been read at this time, download ratio: unknown" +
- "(" + this.bytesRead + "/...)");
- }
- break;
- case TRANSFER_COMPLETED_EVENT:
- this.succeed = true;
- System.out.println("Succeed to download, " + this.bytesRead + " bytes have been transferred in total");
- break;
- case TRANSFER_FAILED_EVENT:
- System.out.println("Failed to download, " + this.bytesRead + " bytes have been transferred");
- break;
- default:
- break;
- }
- }
- public boolean isSucceed() {
- return succeed;
- }
- }
- public static void main(String[] args) {
- String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
- String accessKeyId = "<accessKeyId>";
- String accessKeySecret = "<accessKeySecret>";
- String bucketName = "<bucketName>";
- String key = "object-get-progress-sample";
- OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
- try {
- // 带进度条的下载
- client.getObject(new GetObjectRequest(bucketName, key).
- <GetObjectRequest>withProgressListener(new GetObjectProgressListener()),
- new File("<yourLocalFile>"));
- } catch (Exception e) {
- e.printStackTrace();
- }
- ossClient.shutdown();
- }
提示:
- putObject/getObject/uploadPart都支持进度条功能;
- uploadFile/downloadFile不支持进度条功能。