Uploading large files can be challenging because of potential network interruptions and long transfer times. Multipart upload addresses these issues by splitting a file into smaller parts that are uploaded concurrently. This method supports resumable uploads and improves transfer performance, making it effective for file transfers in unstable network environments.
How it works
Multipart upload splits a large file into multiple smaller parts that are processed independently. Each part is uploaded and verified separately. If a part fails to upload, you only need to re-upload that specific part instead of the entire file. Multipart upload uses an Upload ID to identify the task and ensure that all parts are correctly associated with the same upload. The core process consists of three steps:
Initialize the upload task: Call the InitiateMultipartUpload API to create a multipart upload task and obtain a unique Upload ID to identify the task in subsequent operations.
Upload parts: You can split the file into multiple parts and upload them concurrently. The size of each part can range from 100 KB to 5 GB. This step supports resumable uploads.
Complete the upload: Call the CompleteMultipartUpload API to merge all uploaded parts in order by part number to create a complete object.
Implement multipart upload for large files
Due to a policy change to improve compliance and security, starting March 20, 2025, new OSS users must use a custom domain name (CNAME) to perform data API operations on OSS buckets located in Chinese mainland regions. Default public endpoints are restricted for these operations. Refer to the official announcement for a complete list of the affected operations. If you access your data via HTTPS, you must bind a valid SSL Certificate to your custom domain. This is mandatory for OSS Console access, as the console enforces HTTPS.
You can use graphical tools, command-line tools, or software development kits (SDKs) to implement multipart upload, depending on your application scenario and technical requirements.
The OSS console does not support multipart upload operations.
You can upload encrypted compressed files, but you cannot upload directories.
Automatic part splitting with tools
For daily development, testing, operations and maintenance (O&M), or manual upload scenarios, we recommend that you use graphical or command-line tools. These tools automatically handle the part splitting logic and are easy to use.
ossbrowser, a graphical management tool
When you use ossbrowser 2.0, a graphical management tool, to upload files, the multipart upload mechanism is enabled by default and provides visual monitoring of upload progress and status.
ossutil, a command-line tool
When you use the cp command of ossutil 2.0, a command-line tool, to upload a file, the tool automatically enables multipart upload for files larger than 100 MiB to improve the success rate and transfer efficiency of large file uploads. To manually control the multipart upload process, you can use the initiate-multipart-upload, upload-part, and complete-multipart-upload commands together.
ossutil cp example.zip oss://example-bucket
Programmatic part splitting with SDKs
SDKs for various languages provide complete encapsulation for multipart upload APIs and support custom part sizes, concurrency control, and error handling. The following are examples of multipart upload that use SDKs for common languages. For code samples in other languages, see the examples for the corresponding language in SDK Reference.
Before you run the code, you must install the SDK for the corresponding language and configure environment variables for your access credentials. If you use a Resource Access Management (RAM) user or RAM role, you must also grant the required permissions for the API operations. For more information, see API and permission reference.
Java SDK V2
import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.StaticCredentialsProvider;
import com.aliyun.sdk.service.oss2.io.BoundedInputStream;
import com.aliyun.sdk.service.oss2.models.*;
import com.aliyun.sdk.service.oss2.transport.BinaryData;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* OSS multipart upload example
* Implements multipart upload for large files.
*/
public class MultipartUpload {
public static void main(String[] args) {
// Obtain access credentials from environment variables.
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Set the OSS region and endpoint.
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// Configure bucket and file information.
String bucket = "example-bucket";
String key = "dest.jpg";
String filePath = "dest.jpg";
// Create a credential provider.
CredentialsProvider provider = new StaticCredentialsProvider(accessKeyId, accessKeySecret);
// Initialize the OSS client.
OSSClient client = OSSClient.newBuilder()
.credentialsProvider(provider)
.region(region)
.endpoint(endpoint)
.build();
try {
// Step 1: Initialize the multipart upload.
InitiateMultipartUploadResult initiateResult = client.initiateMultipartUpload(
InitiateMultipartUploadRequest.newBuilder()
.bucket(bucket)
.key(key)
.build());
String uploadId = initiateResult.initiateMultipartUpload().uploadId();
System.out.printf("Multipart upload initialized successfully. Status code: %d, Request ID: %s, Upload ID: %s\n",
initiateResult.statusCode(), initiateResult.requestId(), uploadId);
// Step 2: Upload parts.
File file = new File(filePath);
long fileSize = file.length();
long partSize = 100 * 1024; // 100 KB per part
int partNumber = 1;
List<Part> uploadParts = new ArrayList<>();
for (long start = 0; start < fileSize; start += partSize) {
long curPartSize = Math.min(partSize, fileSize - start);
// Read the file part and upload it.
try (InputStream is = new FileInputStream(file)) {
is.skip(start);
BoundedInputStream boundedInputStream = new BoundedInputStream(is, curPartSize);
// Upload the part.
UploadPartResult partResult = client.uploadPart(UploadPartRequest.newBuilder()
.bucket(bucket)
.key(key)
.uploadId(uploadId)
.partNumber((long) partNumber)
.body(BinaryData.fromStream(boundedInputStream))
.build());
System.out.printf("Status code: %d, Request ID: %s, Part number: %d, ETag: %s\n",
partResult.statusCode(), partResult.requestId(), partNumber, partResult.eTag());
uploadParts.add(Part.newBuilder()
.partNumber((long) partNumber)
.eTag(partResult.eTag())
.build());
}
partNumber++;
}
// Step 3: Complete the multipart upload.
uploadParts.sort((p1, p2) -> p1.partNumber().compareTo(p2.partNumber()));
CompleteMultipartUpload completeMultipartUpload = CompleteMultipartUpload.newBuilder()
.parts(uploadParts)
.build();
CompleteMultipartUploadResult completeResult = client.completeMultipartUpload(
CompleteMultipartUploadRequest.newBuilder()
.bucket(bucket)
.key(key)
.uploadId(uploadId)
.completeMultipartUpload(completeMultipartUpload)
.build());
System.out.printf("Multipart upload completed. Status code: %d, Request ID: %s, Bucket: %s, Key: %s, Location: %s, ETag: %s\n",
completeResult.statusCode(), completeResult.requestId(),
completeResult.completeMultipartUpload().bucket(),
completeResult.completeMultipartUpload().key(),
completeResult.completeMultipartUpload().location(),
completeResult.completeMultipartUpload().eTag());
} catch (Exception e) {
System.out.printf("Error:\n%s", e);
e.printStackTrace();
} finally {
// Close the client connection.
try {
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}Java SDK V1
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* OSS multipart upload example (V1 SDK)
* Implements multipart upload for large files.
*/
public class MultipartUpload {
public static void main(String[] args) {
// Obtain access credentials from environment variables.
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Set the OSS region and endpoint.
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// Configure bucket and file information.
String bucketName = "example-bucket";
String objectName = "dest.jpg";
String filePath = "dest.jpg";
// Create a credential provider.
DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// Configure client parameters.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Initialize the OSS client.
OSS ossClient = OSSClientBuilder.create()
.credentialsProvider(provider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.endpoint(endpoint)
.build();
try {
// Step 1: Initialize the multipart upload.
InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest(bucketName, objectName);
InitiateMultipartUploadResult initiateResult = ossClient.initiateMultipartUpload(initiateRequest);
String uploadId = initiateResult.getUploadId();
System.out.printf("Multipart upload initialized successfully. Upload ID: %s\n", uploadId);
// Step 2: Upload parts.
File file = new File(filePath);
long fileLength = file.length();
long partSize = 100 * 1024L; // 100 KB per part
// Calculate the number of parts.
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Save the ETags of the uploaded parts.
List<PartETag> partETags = new ArrayList<>();
// Traverse and upload parts.
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
// Create a part upload request.
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setPartNumber(i + 1);
uploadPartRequest.setPartSize(curPartSize);
// Read the file part and upload it.
try (InputStream instream = new FileInputStream(file)) {
instream.skip(startPos);
uploadPartRequest.setInputStream(instream);
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
partETags.add(uploadPartResult.getPartETag());
System.out.printf("Part %d/%d uploaded successfully. ETag: %s\n",
i + 1, partCount, uploadPartResult.getPartETag().getETag());
}
}
// Step 3: Complete the multipart upload.
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(
bucketName, objectName, uploadId, partETags);
CompleteMultipartUploadResult completeResult = ossClient.completeMultipartUpload(completeRequest);
System.out.printf("Multipart upload completed. ETag: %s\n", completeResult.getETag());
} catch (Exception e) {
System.out.printf("Error: %s\n", e.getMessage());
e.printStackTrace();
} finally {
// Close the client connection.
ossClient.shutdown();
}
}
}Python SDK V2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# OSS Python SDK V2 multipart upload example
# Implements multipart upload for large files.
import alibabacloud_oss_v2 as oss
import os
def main():
# Obtain access credentials from environment variables.
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# Load the default SDK configuration.
config = oss.config.load_default()
config.credentials_provider = credentials_provider
# Set the OSS region and endpoint.
config.region = "cn-hangzhou"
config.endpoint = "oss-cn-hangzhou.aliyuncs.com"
# Initialize the OSS client.
client = oss.Client(config)
# Configure bucket and file information.
bucket = "example-bucket"
key = "dest.jpg"
file_path = "dest.jpg"
try:
# Step 1: Initialize the multipart upload.
initiate_result = client.initiate_multipart_upload(
oss.InitiateMultipartUploadRequest(
bucket=bucket,
key=key
))
upload_id = initiate_result.upload_id
print(f"Multipart upload initialized successfully. Status code: {initiate_result.status_code}, "
f"Request ID: {initiate_result.request_id}, Upload ID: {upload_id}")
# Step 2: Upload parts.
file_size = os.path.getsize(file_path)
part_size = 100 * 1024 # 100 KB per part
part_number = 1
upload_parts = []
offset = 0
with open(file_path, 'rb') as f:
while offset < file_size:
# Calculate the current part size.
current_part_size = min(part_size, file_size - offset)
# Read the part data.
f.seek(offset)
part_data = f.read(current_part_size)
# Upload the part.
part_result = client.upload_part(
oss.UploadPartRequest(
bucket=bucket,
key=key,
upload_id=upload_id,
part_number=part_number,
body=part_data
))
print(f"Status code: {part_result.status_code}, Request ID: {part_result.request_id}, "
f"Part number: {part_number}, ETag: {part_result.etag}")
# Record the information of the uploaded part.
upload_parts.append(oss.UploadPart(
part_number=part_number,
etag=part_result.etag
))
offset += current_part_size
part_number += 1
# Step 3: Complete the multipart upload.
upload_parts.sort(key=lambda p: p.part_number)
complete_result = client.complete_multipart_upload(
oss.CompleteMultipartUploadRequest(
bucket=bucket,
key=key,
upload_id=upload_id,
complete_multipart_upload=oss.CompleteMultipartUpload(
parts=upload_parts
)
))
print(f"Multipart upload completed. Status code: {complete_result.status_code}, "
f"Request ID: {complete_result.request_id}, "
f"Bucket: {complete_result.bucket}, "
f"Key: {complete_result.key}, "
f"Location: {complete_result.location}, "
f"ETag: {complete_result.etag}")
except Exception as e:
print(f"Error: {e}")
raise
if __name__ == "__main__":
main()
Python SDK V1
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# OSS Python SDK V1 multipart upload example
# Implements multipart upload for large files.
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2 import SizedFileAdapter
from oss2.models import PartInfo
def main():
# Obtain access credentials from environment variables.
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Set the OSS region and endpoint.
region = "cn-hangzhou"
endpoint = "oss-cn-hangzhou.aliyuncs.com"
# Configure bucket and file information.
bucket_name = "example-bucket"
key = "dest.jpg"
file_path = "dest.jpg"
# Initialize the OSS bucket.
bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)
try:
# Step 1: Initialize the multipart upload.
upload_id = bucket.init_multipart_upload(key).upload_id
print(f"Multipart upload initialized successfully. Upload ID: {upload_id}")
# Step 2: Upload parts.
file_size = os.path.getsize(file_path)
part_size = 100 * 1024 # 100 KB per part
part_number = 1
parts = []
offset = 0
with open(file_path, 'rb') as fileobj:
while offset < file_size:
# Calculate the current part size.
current_part_size = min(part_size, file_size - offset)
# Upload the part.
result = bucket.upload_part(
key,
upload_id,
part_number,
SizedFileAdapter(fileobj, current_part_size)
)
print(f"Part number: {part_number}, ETag: {result.etag}")
# Record the information of the uploaded part.
parts.append(PartInfo(part_number, result.etag))
offset += current_part_size
part_number += 1
# Step 3: Complete the multipart upload.
result = bucket.complete_multipart_upload(key, upload_id, parts)
print(f"Multipart upload completed. ETag: {result.etag}")
except Exception as e:
print(f"Error: {e}")
raise
if __name__ == "__main__":
main()
Go SDK V2
package main
// OSS Go SDK V2 multipart upload example
// Implements multipart upload for large files.
import (
"context"
"fmt"
"io"
"os"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
func main() {
// Obtain access credentials from environment variables.
// Configure the OSS client, set the credential provider and endpoint.
config := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion("cn-hangzhou").
WithEndpoint("oss-cn-hangzhou.aliyuncs.com")
// Initialize the OSS client.
client := oss.NewClient(config)
// Configure bucket and file information.
bucket := "example-bucket"
key := "dest.jpg"
filePath := "dest.jpg"
// Step 1: Initialize the multipart upload.
initResult, err := client.InitiateMultipartUpload(context.TODO(), &oss.InitiateMultipartUploadRequest{
Bucket: oss.Ptr(bucket),
Key: oss.Ptr(key),
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
uploadId := *initResult.UploadId
fmt.Printf("Multipart upload initialized successfully. Upload ID: %s\n", uploadId)
// Step 2: Upload parts.
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fileSize := fileInfo.Size()
partSize := int64(100 * 1024) // 100 KB per part
partNumber := int32(1)
var parts []oss.UploadPart
for offset := int64(0); offset < fileSize; offset += partSize {
// Calculate the current part size.
currentPartSize := partSize
if offset+partSize > fileSize {
currentPartSize = fileSize - offset
}
// Read the part data.
file.Seek(offset, 0)
partData := io.LimitReader(file, currentPartSize)
// Upload the part.
partResult, err := client.UploadPart(context.TODO(), &oss.UploadPartRequest{
Bucket: oss.Ptr(bucket),
Key: oss.Ptr(key),
UploadId: oss.Ptr(uploadId),
PartNumber: partNumber,
Body: partData,
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Part number: %d, ETag: %s\n", partNumber, *partResult.ETag)
// Record the information of the uploaded part.
parts = append(parts, oss.UploadPart{
PartNumber: partNumber,
ETag: partResult.ETag,
})
partNumber++
}
// Step 3: Complete the multipart upload.
completeResult, err := client.CompleteMultipartUpload(context.TODO(), &oss.CompleteMultipartUploadRequest{
Bucket: oss.Ptr(bucket),
Key: oss.Ptr(key),
UploadId: oss.Ptr(uploadId),
CompleteMultipartUpload: &oss.CompleteMultipartUpload{
Parts: parts,
},
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Multipart upload completed. Bucket: %s, Key: %s, Location: %s, ETag: %s\n",
*completeResult.Bucket, *completeResult.Key, *completeResult.Location, *completeResult.ETag)
}
Go SDK V1
package main
// OSS Go SDK V1 multipart upload example
// Implements multipart upload for large files.
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Obtain access credentials from environment variables.
provider, _ := oss.NewEnvironmentVariableCredentialsProvider()
// Create an OSS client instance.
client, _ := oss.New(
"oss-cn-hangzhou.aliyuncs.com",
"",
"",
oss.SetCredentialsProvider(&provider),
oss.AuthVersion(oss.AuthV4),
oss.Region("cn-hangzhou"),
)
// Get the bucket object.
bucket, _ := client.Bucket("example-bucket")
// Configure file information.
key := "dest.jpg"
filePath := "dest.jpg"
// Step 1: Initialize the multipart upload.
imur, err := bucket.InitiateMultipartUpload(key)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Multipart upload initialized successfully. Upload ID: %s\n", imur.UploadID)
// Step 2: Upload parts.
file, err := os.Open(filePath)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fileSize := fileInfo.Size()
partSize := int64(100 * 1024) // 100 KB per part
// Split the file into parts.
chunks, err := oss.SplitFileByPartSize(filePath, partSize)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
var parts []oss.UploadPart
for _, chunk := range chunks {
part, err := bucket.UploadPart(imur, file, chunk.Size, chunk.Number)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Part number: %d, ETag: %s\n", chunk.Number, part.ETag)
parts = append(parts, part)
}
// Step 3: Complete the multipart upload.
_, err = bucket.CompleteMultipartUpload(imur, parts)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Multipart upload completed. File size: %d bytes\n", fileSize)
}
Clean up fragment files
Due to a policy change to improve compliance and security, starting March 20, 2025, new OSS users must use a custom domain name (CNAME) to perform data API operations on OSS buckets located in Chinese mainland regions. Default public endpoints are restricted for these operations. Refer to the official announcement for a complete list of the affected operations. If you access your data via HTTPS, you must bind a valid SSL Certificate to your custom domain. This is mandatory for OSS Console access, as the console enforces HTTPS.
If a multipart upload is interrupted unexpectedly and the AbortMultipartUpload API is not called, the uploaded parts are retained in the bucket as fragments and will continue to incur storage costs. You must promptly clean up these fragments to avoid unnecessary storage costs.
Using the console
Go to the Buckets list and click the target bucket.
In the Files list, click Fragment Management to view and delete fragments.
Using lifecycle rules
You can configure a lifecycle rule to automatically clean up expired parts. This method reduces manual maintenance and prevents parts from being missed. For more information, see Clean up expired parts using a lifecycle rule.
Using tools
ossbrowser, a graphical management tool
In the file list of the bucket, click File Fragments to view and delete fragments.
ossutil, a command-line tool
You can use the abort-multipart-upload command to cancel a multipart upload task and delete the uploaded parts. The following is a sample command:
ossutil api abort-multipart-upload --bucket example-bucket --key dest.jpg --upload-id D9F4****************************
Using SDKs
You can call the AbortMultipartUpload API to cancel a multipart upload task and delete the uploaded parts. The following sections provide code samples that show how to cancel a multipart upload task using SDKs for common languages. For code samples in other languages, see the examples for the corresponding language in SDK Reference.
Before you run the code, you must install the SDK for the corresponding language and configure environment variables for your access credentials. If you use a RAM user or RAM role, you must also grant the required permissions for the API operations. For more information, see API and permission reference.
Java SDK V2
import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.StaticCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.AbortMultipartUploadRequest;
import com.aliyun.sdk.service.oss2.models.AbortMultipartUploadResult;
/**
* OSS cancel multipart upload example
* Demonstrates how to cancel a multipart upload task.
*/
public class AbortMultipartUpload {
public static void main(String[] args) {
// Obtain access credentials from environment variables.
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Set the OSS region and endpoint.
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// Configure bucket and file information.
String bucket = "example-bucket";
String key = "dest.jpg";
String uploadId = "D9F4****************************";
// Create a credential provider.
CredentialsProvider provider = new StaticCredentialsProvider(accessKeyId, accessKeySecret);
// Initialize the OSS client.
OSSClient client = OSSClient.newBuilder()
.credentialsProvider(provider)
.region(region)
.endpoint(endpoint)
.build();
try {
// Cancel the multipart upload.
AbortMultipartUploadResult result = client.abortMultipartUpload(
AbortMultipartUploadRequest.newBuilder()
.bucket(bucket)
.key(key)
.uploadId(uploadId)
.build());
System.out.printf("Multipart upload canceled successfully. Status code: %d, Request ID: %s\n",
result.statusCode(), result.requestId());
} catch (Exception e) {
System.out.printf("Error: %s\n", e.getMessage());
e.printStackTrace();
} finally {
// Close the client connection.
try {
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}Java SDK V1
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
/**
* OSS cancel multipart upload example (V1 SDK)
* Demonstrates how to cancel a multipart upload task.
*/
public class AbortMultipartUpload {
public static void main(String[] args) {
// Obtain access credentials from environment variables.
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Set the OSS region and endpoint.
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// Configure bucket and file information.
String bucketName = "example-bucket";
String objectName = "dest.jpg";
String uploadId = "D9F4****************************";
// Create a credential provider.
DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// Configure client parameters.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Initialize the OSS client.
OSS ossClient = OSSClientBuilder.create()
.credentialsProvider(provider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.endpoint(endpoint)
.build();
try {
// Cancel the multipart upload.
AbortMultipartUploadRequest abortMultipartUploadRequest =
new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
ossClient.abortMultipartUpload(abortMultipartUploadRequest);
System.out.printf("Multipart upload canceled successfully. Upload ID: %s\n", uploadId);
} catch (Exception e) {
System.out.printf("Error: %s\n", e.getMessage());
e.printStackTrace();
} finally {
// Close the client connection.
ossClient.shutdown();
}
}
}Python SDK V2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# OSS Python SDK V2 cancel multipart upload example
# Cancels a multipart upload task and deletes the uploaded parts.
import alibabacloud_oss_v2 as oss
def main():
# Obtain access credentials from environment variables.
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# Load the default SDK configuration.
config = oss.config.load_default()
config.credentials_provider = credentials_provider
# Set the OSS region and endpoint.
config.region = "cn-hangzhou"
config.endpoint = "oss-cn-hangzhou.aliyuncs.com"
# Initialize the OSS client.
client = oss.Client(config)
# Configure bucket and file information.
bucket = "example-bucket"
key = "dest.jpg"
upload_id = "D9F4****************************"
# Cancel the multipart upload.
result = client.abort_multipart_upload(
oss.AbortMultipartUploadRequest(
bucket=bucket,
key=key,
upload_id=upload_id
))
print(f"Multipart upload canceled successfully. Status code: {result.status_code}, Request ID: {result.request_id}")
if __name__ == "__main__":
main()Python SDK V1
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# OSS Python SDK V1 cancel multipart upload example
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
def main():
# Obtain access credentials from environment variables.
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# Set the OSS region and endpoint.
region = "cn-hangzhou"
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Configure bucket and file information.
bucket_name = "example-bucket"
key = "dest.jpg"
upload_id = "D9F4****************************"
# Initialize the OSS client.
bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)
# Cancel the multipart upload.
bucket.abort_multipart_upload(key, upload_id)
print(f"Multipart upload canceled successfully. Upload ID: {upload_id}")
if __name__ == "__main__":
main()Go SDK V2
package main
// OSS Go SDK V2 cancel multipart upload example
import (
"context"
"fmt"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
func main() {
// Obtain access credentials from environment variables.
// Configure the OSS client, set the credential provider and endpoint.
config := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion("cn-hangzhou").
WithEndpoint("oss-cn-hangzhou.aliyuncs.com")
// Initialize the OSS client.
client := oss.NewClient(config)
// Configure bucket and file information.
bucket := "example-bucket"
key := "dest.jpg"
uploadId := "D9F4****************************"
// Cancel the multipart upload.
client.AbortMultipartUpload(context.TODO(), &oss.AbortMultipartUploadRequest{
Bucket: oss.Ptr(bucket),
Key: oss.Ptr(key),
UploadId: oss.Ptr(uploadId),
})
fmt.Printf("Multipart upload canceled successfully. Upload ID: %s\n", uploadId)
}
Go SDK V1
package main
// OSS Go SDK V1 cancel multipart upload example
import (
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Obtain access credentials from environment variables.
provider, _ := oss.NewEnvironmentVariableCredentialsProvider()
// Create an OSS client instance.
client, _ := oss.New(
"oss-cn-hangzhou.aliyuncs.com",
"",
"",
oss.SetCredentialsProvider(&provider),
oss.AuthVersion(oss.AuthV4),
oss.Region("cn-hangzhou"),
)
// Get the bucket object.
bucket, _ := client.Bucket("example-bucket")
// Configure file information.
key := "dest.jpg"
uploadId := "D9F4****************************"
// Create an InitiateMultipartUploadResult object.
imur := oss.InitiateMultipartUploadResult{
UploadID: uploadId,
Key: key,
}
// Cancel the multipart upload.
bucket.AbortMultipartUpload(imur)
fmt.Printf("Multipart upload canceled successfully. Upload ID: %s\n", uploadId)
}
Going live
Best practices
Performance optimization: Improve upload speed and stability
Control the number of concurrent parts: Determine a reasonable number of concurrent parts based on your network bandwidth and device load. Too many concurrent connections can increase the system load and cause network congestion, while too few may not make full use of your network resources.
Avoid sequential prefixes in object names: When you upload many files, avoid using sequential prefixes, such as timestamp-based prefixes, for object names. This practice prevents requests from being concentrated on a specific partition, which can cause hot spots and affect the overall upload performance. For more information, see Best practices for OSS performance.
Ensure reliability: Implement resumable uploads
Multipart upload tasks do not expire and support pause and resume operations. You can use the Upload ID to identify the task. If a part fails to upload, you need to re-upload only that part. This way, you do not need to upload the entire file from the beginning, which significantly improves transfer efficiency.
Optimize costs: Refine the upload strategy for Deep Cold Archive
To store many files in the Deep Cold Archive storage class, we recommend that you first upload them to the Standard storage class. Then, you can use a lifecycle rule to automatically transition the files to Deep Cold Archive. This strategy helps you avoid the high PUT request fees that are associated with direct uploads to Deep Cold Archive.
Risk prevention
Data security: Prevent object overwrites
You can set the
x-oss-forbid-overwriteparameter totruein the upload request header to prevent existing objects with the same name from being overwritten. This helps prevent accidental data loss. Alternatively, you can enable the versioning feature to retain historical versions of objects.
Quotas and limits
Limit | Description |
Size of a single file | Up to 48.8 TB |
Number of parts | 1 to 10,000 |
Size of a single part | The size can range from 100 KB to 5 GB. The size of the last part can be less than 100 KB. |
Maximum number of parts returned by a single ListParts request | 1,000 |
Maximum number of multipart upload events returned by a single ListMultipartUploads request | 1,000 |
Billing
The following table lists the billable items that are generated by different API operations during the multipart upload process. For more information about billing, see Request fees and Storage fees.
API | Billable item | Description |
InitiateMultipartUpload | PUT-like requests | Request fees are calculated based on the number of successful requests. |
UploadPart | PUT-like requests | Request fees are calculated based on the number of successful requests. |
Storage fees | Storage fees are charged based on the storage class of the parts (which is the same as the object), their actual size, and storage duration. There is no minimum unit of measurement. Billing stops after the parts are deleted or merged into a complete object file. | |
UploadPartCopy | PUT-like requests | Request fees are calculated based on the number of successful requests. |
CompleteMultipartUpload | PUT-like requests | Request fees are calculated based on the number of successful requests. |
Storage fees | Storage fees are charged based on the storage class, size, and duration of the object file. | |
AbortMultipartUpload | PUT-like requests | Request fees are calculated based on the number of successful requests. Important
|
ListMultipartUploads | PUT-like requests | Request fees are calculated based on the number of successful requests. |
ListParts | PUT-like requests | Request fees are calculated based on the number of successful requests. |
API and permission reference
By default, an Alibaba Cloud account has permissions to call all API operations. If you use a RAM user or RAM role to perform multipart uploads, you must grant the required permissions for the API operations. For more information, see RAM policies and Common examples of RAM policies.
API | Action | Description |
InitiateMultipartUpload |
| Initiates a multipart upload task. |
| This permission is required if you specify object tags using x-oss-tagging when you initiate the multipart upload task. | |
| These permissions are required if the object metadata includes X-Oss-Server-Side-Encryption: KMS when you upload an object. | |
| ||
UploadPart |
| Uploads a part. |
UploadPartCopy |
| Permission to read the source object is required when you upload a part by copying data from an existing object. |
| Permission to write to the destination object is required when you upload a part by copying data from an existing object. | |
| Permission to read the specified version of the source object is required if you specify the object version using versionId when you upload a part by copying data from an existing object. | |
CompleteMultipartUpload |
| Merges parts into an object file. |
| This permission is required if you specify object tags using x-oss-tagging when you merge parts into an object file. | |
AbortMultipartUpload |
| Cancels a multipart upload event and deletes the corresponding part data. |
ListMultipartUploads |
| Lists all in-progress multipart upload events that have been initiated but not yet completed or aborted. |
ListParts |
| Lists all successfully uploaded parts that belong to a specified Upload ID. |