Object Storage Service (OSS) propose une fonctionnalité de téléchargement en plusieurs parties. Cette fonctionnalité divise un objet volumineux en plusieurs parties. Une fois ces parties téléchargées, appelez l'opération CompleteMultipartUpload pour les assembler en un objet complet.
Remarques sur l'utilisation
Pour plus d'informations sur les régions et les endpoints pris en charge par OSS, consultez la rubrique Régions et endpoints.
Pour effectuer un téléchargement en plusieurs parties, vous devez disposer de l'autorisation
oss:PutObject. Pour plus d'informations, consultez la section Accorder une politique d'accès personnalisée à un utilisateur RAM.
Processus de téléchargement en plusieurs parties
Un téléchargement en plusieurs parties se déroule en trois étapes :
-
Initiez le téléchargement en plusieurs parties.
Appelez la méthode client.initiateMultipartUpload. OSS renvoie un ID de téléchargement unique au niveau mondial.
-
Téléchargez les parties.
Appelez la méthode client.uploadPart pour télécharger les données de la partie.
RemarquePour un même ID de téléchargement, le numéro de partie (partNumber) identifie la position de la partie dans l'objet complet. Si vous téléchargez une nouvelle partie avec le même numéro de partie, les données existantes de cette partie dans OSS sont écrasées.
OSS renvoie le hachage MD5 de la partie reçue dans l'en-tête ETag.
OSS calcule le hachage MD5 des données téléchargées et le compare au hachage MD5 calculé par le SDK. Si les deux hachages ne correspondent pas, OSS renvoie le code d'erreur InvalidDigest.
-
Finalisez le téléchargement en plusieurs parties.
Une fois toutes les parties téléchargées, appelez la méthode client.completeMultipartUpload pour assembler les parties en un objet complet.
Exemple de code
Le code suivant montre comment diviser un fichier local volumineux en plusieurs parties, télécharger les parties simultanément dans un bucket, puis assembler les parties en un objet complet.
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();