Overview
Object Storage Service (OSS) SDK for Java provides sample code for multipart upload of a local file. In some scenarios, an application server may need to capture data streams and upload them in parts. To implement this task, the application server must save data streams to a local file and upload the local file in parts. The implementation involves upload from intermediary storage, which is non-real-time upload. This topic provides sample code for multipart upload of data streams.
Upload data streams in parts
A multipart upload of data streams involves data stream cloning. The following sample code provides an example on how to perform a multipart upload of data streams.
Note
In the sample code, cloneInputStream is an implementation of data stream cloning.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CompleteMultipartUploadRequest;
import com.aliyun.oss.model.CompleteMultipartUploadResult;
import com.aliyun.oss.model.InitiateMultipartUploadRequest;
import com.aliyun.oss.model.InitiateMultipartUploadResult;
import com.aliyun.oss.model.PartETag;
import com.aliyun.oss.model.UploadPartRequest;
import com.aliyun.oss.model.UploadPartResult;
public class MutilpartUpload {
public static void main(String[] args) {
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console.
String accessKeyId = "xxx";
String accessKeySecret = "xxx";
String bucketName = "dahecs1";
// <yourObjectName> specifies the complete path to the file you want to upload to OSS. The path must include the extension of the file name. Example: abc/efg/123.jpg.
String objectName = "11/aaaatest11123";
String filePath = "/Users/wanghe/Downloads/aaaatest111";
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// Create an InitiateMultipartUploadRequest object.
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// (Optional) Specify the storage class.
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// request.setObjectMetadata(metadata);
// Initiate a multipart upload task.
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// Obtain an upload ID. The upload ID uniquely identifies the multipart upload task. You can use the upload ID to initiate related requests such as canceling and querying a multipart upload task.
String uploadId = upresult.getUploadId();
// partETags is a set of PartETags. The PartETag of a part consists of the part number and ETag value of the part.
List<PartETag> partETags = new ArrayList<PartETag>();
// Calculate the total number of parts to upload.
try {
InputStream instream = new FileInputStream(filePath);
final long partSize = 1 * 1024 * 1024L; // 1MB
final File sampleFile = new File(filePath);
long fileLength1 = sampleFile.length();
long fileLength = instream.available();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Upload all parts.
ByteArrayOutputStream baos = cloneInputStream(instream);
//InputStream stream2 = null;
for (int i = 0; i < partCount; i++) {
System.out.println("i= "+i);
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());
System.out.println("Length"+stream1.available());
//InputStream instream = new FileInputStream(sampleFile);
// Skip the parts that are uploaded.
stream1.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(stream1);
// Specify the part size. Each part except the last part must be equal to or greater than 100 KB.
uploadPartRequest.setPartSize(curPartSize);
// Configure part numbers. Each part has a part number. The part number ranges from 1 to 10000. If you specify a part number beyond the range, OSS returns an InvalidArgument error code.
uploadPartRequest.setPartNumber( i + 1);
// Parts are not necessarily uploaded in sequence and can be uploaded from different OSS clients. OSS sorts the parts based on the part numbers and combines the parts into a complete object.
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// Each time a part is uploaded, OSS returns a result that contains the PartETag of the part. The PartETag is stored in partETags.
partETags.add(uploadPartResult.getPartETag());
if (stream1 != null) {
try {
stream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Create a CompleteMultipartUploadRequest object.
// When you call the CompleteMultipartUpload operation, you must provide all valid PartETags. After OSS receives the partETags, OSS verifies all parts one by one. After all parts are verified, OSS combines these parts into a complete object.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// (Optional) Set the access control list (ACL) of the object.
// completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead);
// Complete the multipart upload task.
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
baos.close();
// Shut down the OSSClient instance.
ossClient.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
}
private static ByteArrayOutputStream cloneInputStream(InputStream input) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
References
Scope
OSS