全部产品
弹性计算 会员服务 网络 安全 移动云 数加·大数据分析及展现 数加·大数据应用 管理与监控 云通信 阿里云办公 培训与认证 智能硬件
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 更多
对象存储 OSS

下载文件

更新时间:2018-06-01 19:07:52

OSS Java SDK提供了丰富的文件下载方式:

  • 流式下载
  • 下载到本地文件
  • 范围下载
  • 断点续传下载
  • 限定条件下载

流式下载

如果要下载的文件太大,或者一次性下载耗时太长,您可以通过流式下载,一次处理部分内容,直到完成文件的下载。

OssObject对象使用完毕后必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。关闭方法如下:

  1. OSSObject ossObject = ossClient.getObject(bucketName, objectName);
  2. ossObject.close();

以下代码用于流式下载:

  1. // Endpoint以杭州为例,其它Region请按实际情况填写。
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. String bucketName = "<yourBucketName>";
  7. String objectName = "<yourObjectName>";
  8. // 创建OSSClient实例。
  9. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  10. //ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
  11. OSSObject ossObject = ossClient.getObject(bucketName, objectName);
  12. // 读取文件内容。
  13. System.out.println("Object content:");
  14. BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
  15. while (true) {
  16. String line = reader.readLine();
  17. if (line == null) break;
  18. System.out.println("\n" + line);
  19. }
  20. //数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
  21. reader.close();
  22. // 关闭Client。
  23. ossClient.shutdown();

流式下载的完整代码请参见GitHub

下载到本地文件

以下代码用于把指定的OSS文件下载到本地文件:

  1. // Endpoint以杭州为例,其它Region请按实际情况填写。
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. String bucketName = "<yourBucketName>";
  7. String objectName = "<yourObjectName>";
  8. // 创建OSSClient实例。
  9. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  10. // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
  11. ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File("<yourLocalFile>"));
  12. // 关闭Client。
  13. ossClient.shutdown();

范围下载

如果仅需要文件中的部分数据,您可以使用范围下载,下载指定范围内的数据,代码如下:

  1. // Endpoint以杭州为例,其它Region请按实际情况填写。
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. String bucketName = "<yourBucketName>";
  7. String objectName = "<yourObjectName>";
  8. // 创建OSSClient实例。
  9. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  10. GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
  11. // 获取0~1000字节范围内的数据,包括0和1000,共1001个字节的数据。如果指定的范围无效(比如开始或结束位置的指定值为负数,或指定值大于文件大小),则下载整个文件。
  12. getObjectRequest.setRange(0, 1000);
  13. // 范围下载。
  14. OSSObject ossObject = ossClient.getObject(getObjectRequest);
  15. // 读取数据。
  16. byte[] buf = new byte[1024];
  17. InputStream in = ossObject.getObjectContent();
  18. for (int n = 0; n != -1; ) {
  19. n = in.read(buf, 0, buf.length);
  20. }
  21. // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
  22. in.close();
  23. // 关闭Client。
  24. ossClient.shutdown();

流式读取一次可能无法读取全部数据。如果您需要流式读取64KB的数据,请使用如下的方式多次读取,直到读取到64KB或者文件结束,详细说明请参见 InputStream.read

  1. byte[] buf = new byte[1024];
  2. InputStream in = ossObject.getObjectContent();
  3. for (int n = 0; n != -1; ) {
  4. n = in.read(buf, 0, buf.length);
  5. }
  6. in.close();

断点续传下载

当下载大文件时,如果网络不稳定或者程序异常退出,会导致下载失败,需要重新下载整个文件,甚至重试多次仍无法完成下载。为此OSS提供了断点续传下载功能。

断点续传下载将需要下载的文件分成若干个分片分别下载,所有分片都下载完成后,将所有分片合并成完整的文件。

您可以通过ossClient.downloadFile方法实现断点续传下载。此方法的DownloadFileRequest请求包含以下参数:

参数 描述 是否必需 默认值 如何设置值
bucket 存储空间名称。 通过构造方法设置。
key OSS文件名称。 通过构造方法设置。
downloadFile 本地文件。OSS文件将下载到该文件。 OSS文件名称 通过构造方法或setDownloadFile设置。
partSize 分片大小,取值范围为1B~5GB。 文件大小/10000 通过setPartSize设置。
taskNum 分片下载的并发数。 1 通过setTaskNum设置。
enableCheckpoint 是否开启断点续传功能。 关闭 通过setEnableCheckpoint设置。
checkpointFile 记录本地分片下载结果的文件。开启断点续传功能时需要设置此参数。下载过程中的进度信息会保存在该文件中,如果某一分片下载失败,再次下载时会根据文件中记录的点继续下载。下载完成后,该文件会被删除。 downloadFile.ucp(与DownloadFile同目录)。 通过setCheckpointFile设置。

以下代码用于断点续传下载:

  1. // Endpoint以杭州为例,其它Region请按实际情况填写。
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. String bucketName = "<yourBucketName>";
  7. String objectName = "<yourObjectName>";
  8. // 创建OSSClient实例。
  9. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  10. // 下载请求,10个任务并发下载,启动断点续传。
  11. DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, objectName);
  12. downloadFileRequest.setDownloadFile("<yourDownloadFile>");
  13. downloadFileRequest.setPartSize(1 * 1024 * 1024);
  14. downloadFileRequest.setTaskNum(10);
  15. downloadFileRequest.setEnableCheckpoint(true);
  16. downloadFileRequest.setCheckpointFile("<yourCheckpointFile>");
  17. // 下载文件。
  18. DownloadFileResult downloadRes = ossClient.downloadFile(downloadFileRequest);
  19. // 下载成功时,会返回文件元信息。
  20. downloadRes.getObjectMeta();
  21. // 关闭Client。
  22. ossClient.shutdown();

限定条件下载

下载文件时,可以指定一个或多个限定条件。满足限定条件则下载,不满足则返回错误,不下载。可以使用的限定条件如下:

参数 描述
If-Modified-Since 如果指定的时间早于实际修改时间,则正常传输文件,否则返回错误(304 Not modified)。
If-Unmodified-Since 如果指定的时间等于或者晚于文件实际修改时间,则正常传输文件,否则返回错误(412 Precondition failed)。
If-Match 如果指定的ETag和OSS文件的ETag匹配,则正常传输文件,否则返回错误(412 Precondition failed)。
If-None-Match 如果指定的ETag和OSS文件的ETag不匹配,则正常传输文件,否则返回错误(304 Not modified)。

If-Modified-Since和If-Unmodified-Since可以同时存在。If-Match和If-None-Match可以同时存在。

ETag可以通过ossClient.getObjectMeta方法获取。

以下代码用于限定条件下载:

  1. // Endpoint以杭州为例,其它Region请按实际情况填写。
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. String bucketName = "<yourBucketName>";
  7. String objectName = "<yourObjectName>";
  8. // 创建OSSClient实例。
  9. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  10. GetObjectRequest request = new GetObjectRequest(bucketName, objectName);
  11. // 设置限定条件。
  12. request.setModifiedSinceConstraint(new Date());
  13. // 下载OSS文件到本地文件。
  14. ossClient.getObject(request, new File("<yourLocalFile>"));
  15. // 关闭Client。
  16. ossClient.shutdown();

ossClient.getObject和ossClient.downloadFile方法支持限定条件下载。

下载进度条

进度条用于指示上传或下载的进度。下面的代码以ossClient.getObject方法为例,介绍如何使用进度条。

  1. static class GetObjectProgressListener implements ProgressListener {
  2. private long bytesRead = 0;
  3. private long totalBytes = -1;
  4. private boolean succeed = false;
  5. @Override
  6. public void progressChanged(ProgressEvent progressEvent) {
  7. long bytes = progressEvent.getBytes();
  8. ProgressEventType eventType = progressEvent.getEventType();
  9. switch (eventType) {
  10. case TRANSFER_STARTED_EVENT:
  11. System.out.println("Start to download......");
  12. break;
  13. case RESPONSE_CONTENT_LENGTH_EVENT:
  14. this.totalBytes = bytes;
  15. System.out.println(this.totalBytes + " bytes in total will be downloaded to a local file");
  16. break;
  17. case RESPONSE_BYTE_TRANSFER_EVENT:
  18. this.bytesRead += bytes;
  19. if (this.totalBytes != -1) {
  20. int percent = (int)(this.bytesRead * 100.0 / this.totalBytes);
  21. System.out.println(bytes + " bytes have been read at this time, download progress: " +
  22. percent + "%(" + this.bytesRead + "/" + this.totalBytes + ")");
  23. } else {
  24. System.out.println(bytes + " bytes have been read at this time, download ratio: unknown" +
  25. "(" + this.bytesRead + "/...)");
  26. }
  27. break;
  28. case TRANSFER_COMPLETED_EVENT:
  29. this.succeed = true;
  30. System.out.println("Succeed to download, " + this.bytesRead + " bytes have been transferred in total");
  31. break;
  32. case TRANSFER_FAILED_EVENT:
  33. System.out.println("Failed to download, " + this.bytesRead + " bytes have been transferred");
  34. break;
  35. default:
  36. break;
  37. }
  38. }
  39. public boolean isSucceed() {
  40. return succeed;
  41. }
  42. }
  43. public static void main(String[] args) {
  44. // Endpoint以杭州为例,其它Region请按实际情况填写。
  45. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  46. // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
  47. String accessKeyId = "<yourAccessKeyId>";
  48. String accessKeySecret = "<yourAccessKeySecret>";
  49. String bucketName = "<yourBucketName>";
  50. String objectName = "<yourObjectName>";
  51. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  52. try {
  53. // 带进度条的下载。
  54. ossClient.getObject(new GetObjectRequest(bucketName, objectName).
  55. <GetObjectRequest>withProgressListener(new GetObjectProgressListener()),
  56. new File("<yourLocalFile>"));
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. }
  60. // 关闭Client。
  61. ossClient.shutdown();
  62. }

ossClient.putObject、ossClient.getObject和ossClient.uploadPart方法支持进度条功能。ossClient.uploadFile和ossClient.downloadFile方法不支持进度条功能。

下载进度条的完整代码请参见GitHub

本文导读目录