In a wireless network environment, it takes a long time to upload a large object and the upload may fail due to poor network connectivity or network switchover. If the upload fails, the entire object must be uploaded again. To resolve this issue, Object Storage Service (OSS) SDK for Android provides the resumable upload feature.
Description
OSS SDK for Android provides the following methods for resumable upload: resumableUpload and sequenceUpload.
- (Recommended) resumableUpload specifies that multiple parts are uploaded in parallel. Up to five parts can be uploaded in parallel.
- sequenceUpload specifies that parts are uploaded sequentially. The next part is uploaded after the previous part is uploaded.
In this topic, the following sample code provides only examples on how to perform resumable upload by using the resumableUpload method. If you want to upload multiple objects by using resumable upload, you must create multiple resumableUpload requests.
Usage notes
We recommend that you do not use resumable upload when you upload objects that are smaller than 5 GB in size from a mobile device. Resumable upload is implemented by using the multipart upload method. Resumable upload of a single object requires multiple network requests, which is inefficient. When you upload an object that is larger than 5 GB in size by using resumable upload, take note of the following items:
- Before resumable upload
Before you upload an object to OSS by using the resumable upload method, you can specify a directory for the checkpoint file that stores resumable upload records. The checkpoint file applies only to the current resumable upload task.
- If you do not specify the directory for the checkpoint file and part of a large object fails to be uploaded due to network issues, it takes a large amount of time and consumes a large amount of traffic to upload the entire large object again.
- If you specify the directory for the checkpoint file, a failed resumable upload task can be resumed from the position recorded in the checkpoint file.
- During resumable upload
- Resumable upload allows you to upload only local files. Resumable upload supports upload callback. You can use resumable upload in a similar way you use upload callback. For more information, see Callback.
- Resumable upload is implemented by calling the following API operations: InitMultipartUpload, UploadPart, ListParts, CompleteMultipartUpload, and AbortMultipartUpload. If you want to use the Security Token Service (STS) authentication mode to perform resumable upload tasks, make sure that you are authorized to call the preceding API operations.
- By default, the MD5 hash of each part is verified in a resumable upload task. Therefore, you do not need to specify the
Content-Md5
header in the request. - When a resumable upload task fails, the uploaded parts become unnecessary in OSS. To resolve this issue, you can configure lifecycle rules for the bucket that contains the parts to clear the parts on a regular basis. For more information, see Configure lifecycle rules.
Examples
You can use resumable upload to synchronously or asynchronously upload a local file to OSS.
Synchronously upload a local file by using resumable upload
The following code provides an example on how to synchronously upload a local file named examplefile.txt to the exampledir directory in the examplebucket bucket. After the local file is uploaded, the object is named exampleobject.txt. The checkpoint file is stored in your computer.
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: /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);
// Make sure that the directory that is used to store the checkpoint file exists. If the directory does not exist, create a directory.
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// Create a resumable upload request and specify the absolute path of the checkpoint file.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// Set the DeleteUploadOnCancelling parameter to false when the OSSAsyncTask cancel() method is used. false indicates that the checkpoint file is retained. The object is uploaded from the position recorded in the checkpoint file during the next upload. If you do not specify this parameter, the default value true is used. True indicates that the checkpoint file is deleted. The entire object is re-uploaded during the next upload.
request.setDeleteUploadOnCancelling(false);
// Configure an upload callback.
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);
For partition storage of Android 10 and later, you can use the Uniform Resource Identifier (URI) of an object to upload the object to OSS.
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// Make sure that the directory that is used to store the checkpoint file exists. If the directory does not exist, create a directory.
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// Create a resumable upload request and specify the absolute path of the checkpoint file.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// Set the DeleteUploadOnCancelling parameter to false when the OSSAsyncTask cancel() method is used. false indicates that the checkpoint file is retained. The object is uploaded from the position recorded in the checkpoint file during the next upload. If you do not specify this parameter, the default value true is used. True indicates that the checkpoint file is deleted. The entire object is re-uploaded during the next upload.
request.setDeleteUploadOnCancelling(false);
// Configure an upload callback.
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);
The following code provides an example on how to perform resumable upload without storing the checkpoint file in your computer:
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: /storage/emulated/0/oss/examplefile.txt.
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
// Create a resumable upload request.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);
// Configure an upload callback.
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);
Asynchronously upload a local file by using resumable upload
The following code provides an example on how to asynchronously upload a local file named examplefile.txt to the exampledir directory in the examplebucket bucket. After the local file is uploaded, the object is named exampleobject.txt. The checkpoint file is stored in your computer.
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: /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);
// Make sure that the directory that is used to store the checkpoint file exists. If the directory does not exist, create a directory.
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// Create a resumable upload request and specify the absolute path of the checkpoint file.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// Set the DeleteUploadOnCancelling parameter to false when the OSSAsyncTask cancel() method is used. false indicates that the checkpoint file is retained. The object is uploaded from the position recorded in the checkpoint file during the next upload. If you do not specify this parameter, the default value true is used. True indicates that the checkpoint file is deleted. The entire object is re-uploaded during the next upload.
request.setDeleteUploadOnCancelling(false);
// Configure an upload callback.
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) {
// Handle exceptions.
}
});
// Wait until the resumable upload task is complete.
resumableTask.waitUntilFinished();
For partition storage of Android 10 and later, you can use the Uniform Resource Identifier (URI) of an object to upload the object to OSS.
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// Make sure that the directory that is used to store the checkpoint file exists. If the directory does not exist, create a directory.
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// Create a resumable upload request and specify the absolute path of the checkpoint file.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// Set the DeleteUploadOnCancelling parameter to false when the OSSAsyncTask cancel() method is used. false indicates that the checkpoint file is retained. The object is uploaded from the position recorded in the checkpoint file during the next upload. If you do not specify this parameter, the default value true is used. True indicates that the checkpoint file is deleted. The entire object is re-uploaded during the next upload.
request.setDeleteUploadOnCancelling(false);
// Configure an upload callback.
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) {
// Handle exceptions.
}
});
// Wait until the resumable upload task is complete.
resumableTask.waitUntilFinished();
The following code provides an example on how to perform resumable upload without storing the checkpoint file in your computer:
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path of the object.
String objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: /storage/emulated/0/oss/examplefile.txt.
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
// Create a resumable upload request.
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);
// Configure an upload callback.
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
@Override
public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
// Call the asyncResumableUpload method to perform the resumable upload task.
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) {
// Handle exceptions.
}
});
// Wait until the resumable upload task is complete.
resumableTask.waitUntilFinished();