Object Storage Service (OSS) ofrece una función de carga multiparte. Esta función divide un objeto grande en varias partes. Una vez que cargue estas partes, puede llamar a la operación CompleteMultipartUpload para combinarlas en un objeto completo.
Notas de uso
Para obtener más información sobre las regiones y los endpoints que admite OSS, consulte Regions and endpoints.
Para ejecutar una carga multiparte, necesita el permiso
oss:PutObject. Para obtener más información, consulte Grant a custom access policy to a RAM user.
Proceso de carga multiparte
Una carga multiparte consta de los siguientes tres pasos:
-
Inicie un evento de carga multiparte.
Llame al método client.initiateMultipartUpload. OSS devuelve un ID de carga único globalmente.
-
Cargue las partes.
Llame al método client.uploadPart para cargar los datos de la parte.
NotaPara un mismo ID de carga, el número de parte (partNumber) identifica la posición de la parte dentro del objeto completo. Si carga una parte nueva con el mismo número, se sobrescriben los datos existentes de esa parte en OSS.
OSS devuelve el hash MD5 de la parte recibida en el encabezado ETag.
OSS calcula el hash MD5 de los datos cargados y lo compara con el hash MD5 que calculó el SDK. Si ambos hashes no coinciden, OSS devuelve el código de error InvalidDigest.
-
Complete la carga multiparte.
Después de cargar todas las partes, llame al método client.completeMultipartUpload para combinarlas en un objeto completo.
Código de ejemplo
A continuación se muestra cómo dividir un archivo local grande en varias partes, cargarlas de forma simultánea en un bucket y luego combinarlas en un 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();