下載文件__Java-SDK_SDK 參考_對象存儲 OSS-阿裏雲
OSS Java SDK提供了豐富的文件下載接口,用戶可以通過以下方式從OSS中下載文件:
- 流式下載
- 下載到本地文件
- 斷點續傳下載
- 範圍下載
流式下載
在進行大文件下載時,往往不希望一次性處理全部內容,而是希望流式地處理,一次處理一部分內容。
提示:
- 流式下載的完整代碼請參考:GitHub
// endpoint以杭州為例,其它region請按實際情況填寫String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// accessKey請登錄https://ak-console.aliyun.com/#/查看String accessKeyId = "<yourAccessKeyId>";String accessKeySecret = "<yourAccessKeySecret>";String bucketName = "<yourBucketName>";// 創建OSSClient實例OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);OSSObject ossObject = ossClient.getObject(bucketName, "yourKey");// 讀Object內容System.out.println("Object content:");BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));while (true) {String line = reader.readLine();if (line == null) break;System.out.println("n" + line);}reader.close();// 關閉clientossClient.shutdown();
提示:
- OSSObject實例包含文件所在的存儲空間(Bucket)、文件的名稱、Object Metadata以及一個輸入流;
- 通過操作輸入流將文件的內容讀取到文件或者內存中。而Object Metadata包含ETag、HTTP Header及自定義的元信息;
- OSSClient.getObject獲取的流一定要顯示close,否則會造成資源泄露;
OSSObject ossObject = ossClient.getObject(bucketName, key);ossObject.getObjectContent().close();- 假如需要從OSS流式讀取64KB的數據,請使用如下的方式多次讀取,直到讀取64KB或者文件結束:
而不是如下的形式:
byte[] buf = new byte[1024];InputStream in = ossObject.getObjectContent();for (int n = 0; n != -1; ) {n = in.read(buf, 0, buf.length);}in.close();原因是,流式讀取一次不一定能讀到全部數據,詳細說明請參考 InputStream.read 。
byte[] buf = new byte[64 * 1024];InputStream in = ossObject.getObjectContent();in.read(buf, 0, buf.length);in.close();
下載到本地文件
把Object的內容下載到指定的本地文件中。如果指定的本地文件不存在則會新建。
// endpoint以杭州為例,其它region請按實際情況填寫String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// accessKey請登錄https://ak-console.aliyun.com/#/查看String accessKeyId = "<yourAccessKeyId>";String accessKeySecret = "<yourAccessKeySecret>";String bucketName = "<yourBucketName>";// 創建OSSClient實例OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);// 下載object到文件ossClient.getObject(new GetObjectRequest(bucketName, "<yourKey>"), new File("<yourLocalFile>"));// 關閉clientossClient.shutdown();
範圍下載
如果OSS文件較大,並且隻需要其中一部分數據,可以使用範圍下載,下載指定範圍的數據。如果指定的下載範圍是0 - 100,則返回第0到第100個字節的數據,包括第100個,共101字節的數據,即[0, 100]。如果指定的範圍無效,則傳送整個文件。
// endpoint以杭州為例,其它region請按實際情況填寫String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// accessKey請登錄https://ak-console.aliyun.com/#/查看String accessKeyId = "<yourAccessKeyId>";String accessKeySecret = "<yourAccessKeySecret>";String bucketName = "<yourBucketName>";// 創建OSSClient實例OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, "<yourKey>");// 獲取0~1000字節範圍內的數據,包括0和1000,共1001個字節的數據getObjectRequest.setRange(0, 1000);// 範圍下載OSSObject ossObject = ossClient.getObject(getObjectRequest);// 讀取數據byte[] buf = new byte[1024];InputStream in = ossObject.getObjectContent();for (int n = 0; n != -1; ) {n = in.read(buf, 0, buf.length);}// InputStream數據讀完成後,一定要close,否則會造成連接泄漏in.close();// 關閉clientossClient.shutdown();
提示:
- 如果指定的Range無效(比如開始位置、結束位置為負數,大於文件大小),則會下載整個文件;
- 假如需要從OSS流式讀取64KB的數據,請使用如下的方式多次讀取,直到讀取64KB或者文件結束:
而不是如下的形式:
byte[] buf = new byte[1024];InputStream in = ossObject.getObjectContent();for (int n = 0; n != -1; ) {n = in.read(buf, 0, buf.length);}in.close();原因是,流式讀取一次不一定能讀到全部數據,詳細說明請參考 InputStream.read 。
byte[] buf = new byte[64 * 1024];InputStream in = ossObject.getObjectContent();in.read(buf, 0, buf.length);in.close();
斷點續傳下載
當下載大文件時,如果網絡不穩定或者程序崩潰了,則整個下載就失敗了。用戶不得不重頭再來,這樣做不僅浪費資源,在網絡不穩定的情況下,往往重試多次還是無法完成下載。通過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 = "https://oss-cn-hangzhou.aliyuncs.com";// accessKey請登錄https://ak-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();// 關閉clientossClient.shutdown();
限定條件下載
下載文件時,可以指定一個或多個限定條件,滿足限定條件時下載,不滿足時報錯,不下載文件。可以使用的限定條件如下:
| 參數 | 說明 |
|---|---|
| If-Modified-Since | 如果指定的時間早於實際修改時間,則正常傳送。否則返回錯誤。 |
| If-Unmodified-Since | 如果傳入參數中的時間等於或者晚於文件實際修改時間,則正常傳輸文件;否則返回錯誤。 |
| If-Match | 如果傳入期望的ETag和object的 ETag匹配,則正常傳輸;否則返回錯誤。 |
| If-None-Match | 如果傳入的ETag值和Object的ETag不匹配,則正常傳輸;否則返回錯誤。 |
注意:
- 如果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 = "https://oss-cn-hangzhou.aliyuncs.com";// accessKey請登錄https://ak-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>"));// 關閉clientossClient.shutdown();
提示:
- ETag的值可以通過OSSClient.getObjectMetadata獲取;
- OSSClient.getObject,OSSClient.downloadFile都支持限定條件。
下載進度條
OSS Java sdk支持進度條功能,指示上傳/下載的進度。下麵的代碼以OSSClient.getObject為例,說明進度條功能的使用。
提示:
- 下載進度條的完整代碼請參考:GitHub
static class GetObjectProgressListener implements ProgressListener {private long bytesRead = 0;private long totalBytes = -1;private boolean succeed = false;@Overridepublic 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 = "https://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不支持進度條功能。
最後更新:2016-11-23 16:04:10
上一篇:
管理Bucket__Java-SDK_SDK 參考_對象存儲 OSS-阿裏雲
下一篇:
管理文件__Java-SDK_SDK 參考_對象存儲 OSS-阿裏雲
OSSWriter__Writer插件_使用手冊_數據集成-阿裏雲
安全組__網絡和安全性_產品簡介_雲服務器 ECS-阿裏雲
限製說明__產品簡介_雲數據庫 Memcache 版-阿裏雲
阿裏雲與中科院合作發布量子計算雲平台,潘建偉透露研發目標
附錄:PPAS 兼容性說明__快速入門(PPAS)_雲數據庫 RDS 版-阿裏雲
堡壘機__使用金融雲產品_金融雲-阿裏雲
新建測試___Lite用戶使用手冊_性能測試-阿裏雲
CreateLoadBalancerUDPListener__Listener相關API_API 參考_負載均衡-阿裏雲
如何參加線上培訓課程__線上培訓課程_上雲培訓-阿裏雲
分配公網 IP 地址__網絡相關接口_API 參考_雲服務器 ECS-阿裏雲
相關內容
常見錯誤說明__附錄_大數據計算服務-阿裏雲
發送短信接口__API使用手冊_短信服務-阿裏雲
接口文檔__Android_安全組件教程_移動安全-阿裏雲
運營商錯誤碼(聯通)__常見問題_短信服務-阿裏雲
設置短信模板__使用手冊_短信服務-阿裏雲
OSS 權限問題及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
消息通知__操作指南_批量計算-阿裏雲
設備端快速接入(MQTT)__快速開始_阿裏雲物聯網套件-阿裏雲
查詢API調用流量數據__API管理相關接口_API_API 網關-阿裏雲
使用STS訪問__JavaScript-SDK_SDK 參考_對象存儲 OSS-阿裏雲