O Object Storage Service (OSS) oferece o recurso de upload multipartido. Esse mecanismo divide um objeto grande em várias partes. Após enviar essas partes, chame a operação CompleteMultipartUpload para combiná-las em um objeto completo.
Observações de uso
Para obter mais informações sobre as regiões e endpoints compatíveis com o OSS, consulte Regiões e endpoints.
Para realizar um upload multipartido, você precisa da permissão
oss:PutObject. Para mais detalhes, consulte Conceder uma política de acesso personalizada a um usuário do RAM.
Processo de upload multipartido
O upload multipartido consiste nas três etapas a seguir:
-
Inicie um evento de upload multipartido.
Chame o método client.initiateMultipartUpload. O OSS retorna um ID de upload globalmente único.
-
Envie as partes.
Chame o método client.uploadPart para enviar os dados da parte.
NotaPara um mesmo ID de upload, o número da parte (partNumber) identifica a posição dela no objeto completo. Se você enviar uma nova parte com o mesmo número, os dados existentes dessa parte no OSS serão sobrescritos.
O OSS retorna o hash MD5 da parte recebida no cabeçalho ETag.
O OSS calcula o hash MD5 dos dados enviados e o compara com o hash calculado pelo SDK. Se os dois hashes não coincidirem, o OSS retornará o código de erro InvalidDigest.
-
Conclua o upload multipartido.
Após enviar todas as partes, chame o método client.completeMultipartUpload para combinar as partes em um objeto completo.
Código de exemplo
O código a seguir mostra como dividir um arquivo local grande em várias partes, enviar as partes para um bucket simultaneamente e, em seguida, combiná-las em um objeto completo.
import Client, { FilePath, RequestError, THarmonyEmptyBodyApiRes } from '@aliyun/oss';
import { fileIo as fs } from '@kit.CoreFileKit';
// Create an OSS client instance.
const client = new Client({
// Replace with the AccessKey ID from your STS temporary access credential.
accessKeyId: 'yourAccessKeyId',
// Replace with the AccessKey secret from your STS temporary access credential.
accessKeySecret: 'yourAccessKeySecret',
// Replace with the security token from your STS temporary access credential.
securityToken: 'yourSecurityToken',
// Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to oss-cn-hangzhou.
region: 'oss-cn-hangzhou',
});
// Specify the name of the bucket. Replace with your actual bucket name.
const bucket = 'yourBucketName';
// Specify the name of the object (file) to upload. Replace with your actual object name.
const key = 'yourObjectName';
/**
* Upload a file to OSS using multipart upload.
* Use multipart upload to split a large file into multiple parts and upload them to a specified bucket and key.
*/
const multipartUpload = async () => {
try {
// Initiate the multipart upload task and get the uploadId.
const initRes = await client.initiateMultipartUpload({
bucket, // The bucket name.
key, // The object (file) name.
});
// Get the uploadId from the initialization response. This ID is used for subsequent part uploads and to complete the upload.
const uploadId = initRes.data.uploadId;
// Specify the local file path.
const filePath = new FilePath('yourFilePath');// Replace with the actual local file path.
// Get the file metadata, such as the file size.
const fileStat = await fs.stat(filePath.filePath);
// Define the size of each part (10 MB).
const chunkSize = 1024 * 1024 * 10;
// Calculate the total number of parts.
let totalParts = Math.ceil(fileStat.size / chunkSize);
// The current part number.
let partNumber = 1;
// Store the Promise objects for all part uploads.
const waitList: Promise<THarmonyEmptyBodyApiRes>[] = [];
// Loop through each part.
while (partNumber <= totalParts) {
// Calculate the start position of the current part.
const offset = (partNumber - 1) * chunkSize;
// Call the uploadPart method to upload the current part.
const uploadPromise = client.uploadPart({
bucket, // The bucket name.
key, // The object (file) name.
uploadId, // The uploadId returned from the initialization.
partNumber, // The current part number.
data: filePath, // The file path.
length: Math.min(chunkSize, fileStat.size - offset), // The size of the current part.
offset, // The start offset of the current part.
});
// Add the part upload Promise to the wait list.
waitList.push(uploadPromise);
// Increment the part number.
partNumber++;
}
// Wait for all part uploads to complete.
const uploadResList = await Promise.all(waitList);
// After all parts are uploaded, call completeMultipartUpload to complete the upload task.
const completeRes = await client.completeMultipartUpload({
bucket, // The bucket name.
key, // The object (file) name.
uploadId, // The uploadId returned from the initialization.
completeAll: true, // Automatically completes all parts.
});
// Print the result of the completed multipart upload.
console.log(JSON.stringify(completeRes));
} catch (err) {
// Catch exceptions that occur during the request.
if (err instanceof RequestError) {
// If a known type of error occurs, print information such as the error code, error message, request ID, and status code.
console.log('code: ', err.code); // Error code.
console.log('message: ', err.message); // Error message.
console.log('requestId: ', err.requestId); // Request ID.
console.log('status: ', err.status); // HTTP status code.
console.log('ec: ', err.ec); // Error code.
} else {
// Print other unknown types of errors.
console.log('unknown error: ', err);
}
}
};
// Call the multipartUpload function to perform the multipart upload operation.
multipartUpload();