Object Storage Service (OSS) propose une fonctionnalité de téléchargement multipart pour les objets volumineux. Ce processus consiste à diviser un objet volumineux en parties plus petites, à les télécharger indépendamment, puis à appeler l'API CompleteMultipartUpload pour assembler les parties en un seul objet. Cette approche permet de reprendre les téléchargements interrompus.
Notes
Cette rubrique utilise le point de terminaison public de la région Chine (Hangzhou). Pour accéder à OSS depuis d'autres services Alibaba Cloud dans la même région, utilisez un point de terminaison interne. Pour obtenir la liste des régions et des points de terminaison pris en charge, consultez Régions et points de terminaison.
Dans cette rubrique, les identifiants d'accès sont récupérés à partir des variables d'environnement. Pour plus d'informations, consultez Configuration des identifiants d'accès.
Cette rubrique illustre la création d'une instance OSSClient avec un point de terminaison OSS. Pour d'autres configurations, telles que l'utilisation d'un domaine personnalisé ou l'authentification via des identifiants du Security Token Service (STS), consultez Configuration du client.
Le téléchargement multipart utilise les opérations InitiateMultipartUpload, UploadPart et CompleteMultipartUpload. Vous devez disposer de l'autorisation
oss:PutObject. Accorder des politiques d'accès personnalisées à un utilisateur RAM.
Processus de téléchargement multipart
Le téléchargement multipart s'effectue en trois étapes :
-
Initialisez un téléchargement multipart.
Appelez ossClient.initiateMultipartUpload. OSS renvoie un ID de téléchargement unique au niveau mondial.
-
Téléchargez les parties.
Appelez ossClient.uploadPart pour télécharger les données de la partie.
RemarqueLe numéro de partie identifie la position d'une partie au sein de l'objet. Le téléchargement de données avec le même numéro de partie écrase la partie existante.
OSS renvoie le hachage MD5 des données de la partie reçues dans l'en-tête ETag de la réponse.
OSS calcule le hachage MD5 des données téléchargées et le compare au hachage calculé par le SDK. En cas de non-concordance, le code d'erreur InvalidDigest est renvoyé.
-
Finalisez le téléchargement multipart.
Une fois toutes les parties téléchargées, appelez ossClient.completeMultipartUpload pour fusionner les parties en un objet complet.
Exemple de code
L'exemple suivant présente le processus complet de téléchargement multipart :
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
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;
public class Demo {
public static void main(String[] args) throws Exception {
// Use the endpoint of the China (Hangzhou) region as an example. Specify the actual endpoint.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the bucket name, for example, examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object, for example, exampledir/exampleobject.txt. The full path cannot contain the bucket name.
String objectName = "exampledir/exampleobject.txt";
// The path of the local file to upload.
String filePath = "D:\\localpath\\examplefile.txt";
// Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou.
String region = "cn-hangzhou";
// Create an OSSClient instance.
// When the OSSClient instance is no longer used, call the shutdown method to release resources.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// Create an InitiateMultipartUploadRequest object.
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// Create an ObjectMetadata object and set the Content-Type.
ObjectMetadata metadata = new ObjectMetadata();
if (metadata.getContentType() == null) {
metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
}
System.out.println("Content-Type: " + metadata.getContentType());
// Bind the metadata to the upload request.
request.setObjectMetadata(metadata);
// Initialize the multipart upload.
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// Return the upload ID.
String uploadId = upresult.getUploadId();
// partETags is a collection of PartETag objects. A PartETag object consists of the ETag and part number of a part.
List<PartETag> partETags = new ArrayList<PartETag>();
// The size of each part. This is used to calculate the number of parts. Unit: bytes.
// The minimum part size is 100 KB, and the maximum part size is 5 GB. The size of the last part can be smaller than 100 KB.
// Set the part size to 1 MB.
final long partSize = 1 * 1024 * 1024L;
// Calculate the number of parts based on the size of the data to upload. The following code provides an example of how to obtain the size of the data to upload from a local file using File.length().
final File sampleFile = new File(filePath);
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Traverse the parts and upload them.
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
// Set the stream of the part to upload.
// The following code provides an example of how to create a FileInputStream object from a local file and skip the specified data using the InputStream.skip() method.
InputStream instream = new FileInputStream(sampleFile);
instream.skip(startPos);
uploadPartRequest.setInputStream(instream);
// Set the part size.
uploadPartRequest.setPartSize(curPartSize);
// Set the part number. Each uploaded part has a part number that ranges from 1 to 10,000. If the part number is not in the range, OSS returns the InvalidArgument error code.
uploadPartRequest.setPartNumber(i + 1);
// Parts do not need to be uploaded in sequence. They can even be uploaded from different clients. OSS sorts the parts by part number to create a complete object.
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// After each part is uploaded, the OSS response includes a PartETag. The PartETag is saved in partETags.
partETags.add(uploadPartResult.getPartETag());
// Close the stream.
instream.close();
}
// Create a CompleteMultipartUploadRequest object.
// When you complete the multipart upload, you must provide all valid partETags. After OSS receives the submitted partETags, it verifies the validity of each part. After all parts are verified, OSS combines these parts into a complete object.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// Complete the multipart upload.
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println("Upload successful, ETag: " + completeMultipartUploadResult.getETag());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught a ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
Scénarios courants
Définir les métadonnées lors de l'initialisation d'un téléchargement multipart
Définir les autorisations d'accès aux objets lors de la finalisation d'un téléchargement multipart
Traiter automatiquement les ETag des parties lors de la finalisation d'un téléchargement multipart
Annuler un téléchargement multipart
Lister les parties téléchargées
Lister les événements de téléchargement multipart
Effectuer un téléchargement multipart pour des flux réseau ou des flux de données
Références
Exemple de code complet : Exemple GitHub.
-
Un téléchargement multipart implique trois opérations API :
Initialiser un téléchargement multipart : InitiateMultipartUpload.
Télécharger une partie : UploadPart.
Finaliser un téléchargement multipart : CompleteMultipartUpload.
Annuler un téléchargement multipart : AbortMultipartUpload.
Lister les parties téléchargées : ListParts.
Lister les téléchargements multipart en cours : ListMultipartUploads.