212
微信
下載文件__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();
// 關閉client
ossClient.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>"));
// 關閉client
ossClient.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();
// 關閉client
ossClient.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();
// 關閉client
ossClient.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>"));
// 關閉client
ossClient.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;
@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 = "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-阿裏雲