在無線網路下,上傳較大的檔案期間長,可能會遇到因為網路條件差、使用者切換網路等原因導致上傳中途失敗,整個檔案需要重新上傳。為此,Android SDK提供了斷點續傳上傳功能。
使用說明
Android SDK提供了resumableUpload以及sequenceUpload兩種方法用於斷點續傳上傳。
(推薦)resumableUpload表示並發上傳分區,即同時支援最多5個分區並發上傳。
sequenceUpload表示順序上傳分區,即上一個分區上傳完成後開始上傳下一個分區。
以下範例程式碼僅提供通過resumableUpload的方法斷點續傳上傳。如果您希望通過斷點續傳的方式上傳多個檔案或視頻,需建立多個ResumableUploadRequest。
注意事項
使用本文樣本前您需要先通過自訂網域名、STS等方式建立OSSClient,具體請參見如何初始化Android端OSSClient執行個體。
對於移動端而言,如果不是大檔案(例如小於5 GB的檔案),不建議使用斷點續傳的方式上傳。斷點續傳上傳是通過分區上傳實現的,上傳單個檔案需要進行多次網路請求,效率不高。對於通過斷點續傳的方式上傳大於5 GB的檔案時:
斷點續傳上傳前
通過斷點續傳上傳的方式將檔案上傳到OSS前,您可以指定斷點記錄的儲存檔案夾。斷點續傳上傳僅在本次上傳生效。
如果未指定斷點記錄的儲存檔案夾,假設某個分區因為網路原因等導致檔案上傳失敗時,將耗用大量的重試時間及流量來重新上傳整個大檔案。
如果指定了斷點記錄的儲存檔案夾,在檔案上傳失敗時,將從斷點記錄處繼續上傳未上傳完成的部分。
斷點續傳上傳時
斷點續傳上傳僅支援上傳本地檔案。斷點續傳上傳支援上傳回調,使用方法與常見的上傳回調類似。具體操作,請參見Callback。
斷點續傳上傳依賴InitMultipartUpload、UploadPart、ListParts、CompleteMultipartUpload、AbortMultipartUpload等介面來實現。如果您需要通過STS鑒權模式來使用斷點續傳上傳,則需要保證您擁有訪問以上API介面的許可權。
斷點續傳上傳預設已開啟每個分區上傳時的MD5校正,因此無需在請求中設定
Content-Md5
頭部。如果同一任務一直未完成續傳,可能會在OSS上積累無用的片段。此時,您可以為Bucket設定生命週期規則來定時清理片段。具體操作,請參見生命週期管理。
範例程式碼
您可以通過同步或者非同步方式斷點續傳上傳本地檔案到OSS。
同步的方式
以下代碼以同步的方式斷點續傳上傳examplefile.txt檔案到目標儲存空間examplebucket中exampledir目錄下的exampleobject.txt檔案,並將斷點記錄檔案儲存到本地。
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為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);
}
});
ResumableUploadResult uploadResult = oss.resumableUpload(request);
對於Android10及之後版本的分區儲存,您可以使用檔案的Uri上傳檔案到OSS。
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
// 這裡參數"fileUri"需要填入檔案的實際Uri值。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為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);
}
});
ResumableUploadResult uploadResult = oss.resumableUpload(request);
如果在斷點續傳上傳時無需將斷點記錄檔案儲存到本地,範例程式碼如下:
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
// 建立斷點續傳上傳請求。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);
// 設定上傳回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
@Override
public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
ResumableUploadResult uploadResult = oss.resumableUpload(request);
非同步方式
以下代碼以非同步方式斷點續傳上傳examplefile.txt檔案到目標儲存空間examplebucket中exampledir目錄下的exampleobject.txt檔案,並將斷點記錄檔案儲存到本地。
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 確保斷點記錄的儲存路徑已存在,如果不存在則建立斷點記錄的儲存路徑。
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立斷點上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為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();
對於Android10及之後版本的分區儲存,您可以使用檔案的Uri上傳檔案到OSS。
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
// 這裡參數"fileUri"需要填入檔案的實際Uri值。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為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();
如果在斷點續傳上傳時無需將斷點記錄檔案儲存到本地,範例程式碼如下:
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
// 建立斷點上傳請求。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);
// 設定上傳過程回調。
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();
相關文檔
關於Bucket設定生命週期規則,請參見生命週期管理。
關於斷點續傳上傳支援上傳回調使用方法,請參見Callback。
關於初始化OSSClient,請參見如何初始化Android端OSSClient執行個體。