Object Storage Service (OSS) ofrece una función de carga multiparte para objetos grandes. Este proceso consiste en dividir un objeto grande en partes más pequeñas, cargarlas de forma independiente y luego invocar la API CompleteMultipartUpload para combinar las partes en un solo objeto. Esto permite realizar cargas reanudables.
Notas
En este tema se utiliza el endpoint público de la región China (Hangzhou). Si desea acceder a OSS desde otros servicios de Alibaba Cloud en la misma región que OSS, utilice un endpoint interno. Para obtener más información sobre las regiones y endpoints de OSS, consulte Regions and endpoints.
En este tema, las credenciales de acceso se obtienen de variables de entorno. Para obtener más información sobre cómo configurar las credenciales de acceso, consulte Configure access credentials.
Este tema muestra cómo crear una instancia de OSSClient con un endpoint de OSS. Para configuraciones alternativas, como el uso de un dominio personalizado o la autenticación con credenciales de Security Token Service (STS), consulte Configure a client (Go SDK V1).
La carga multiparte utiliza InitiateMultipartUpload, UploadPart y CompleteMultipartUpload. Debe contar con el permiso
oss:PutObject. Grant custom access policies to a RAM user.El código de ejemplo de este tema requiere Go SDK V2.2.5 o posterior.
Procedimiento de carga multiparte
La carga multiparte consta de tres pasos:
-
Inicializar una carga multiparte.
Puede invocar el método Bucket.InitiateMultipartUpload. OSS devuelve un ID de carga único a nivel global.
-
Cargar partes.
Puede invocar el método Bucket.UploadPart para cargar los datos de cada parte.
NotaPara un mismo ID de carga, el número de parte identifica la posición relativa de una parte dentro del objeto. Si carga nuevos datos con el mismo número de parte, se sobrescriben los datos existentes de esa parte en OSS.
OSS devuelve el hash MD5 de los datos 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 calcula el SDK. Si ambos hashes MD5 no coinciden, se devuelve el código de error InvalidDigest.
-
Completar la carga multiparte.
Una vez cargadas todas las partes, puede invocar el método Bucket.CompleteMultipartUpload para combinarlas en un objeto completo.
Código de ejemplo
Puede utilizar el siguiente código para realizar una carga multiparte completa.
package main
import (
"fmt"
"log"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 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.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error: %v", err)
}
// Create an OSSClient instance.
// Set yourEndpoint to the endpoint of the bucket. For example, for a bucket in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. For other regions, set the endpoint as needed.
// Set yourRegion to the region where the bucket is located. For example, for a bucket in the China (Hangzhou) region, set the region to cn-hangzhou. For other regions, set the region as needed.
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// Set the signature version.
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error: %v", err)
}
// Set the bucket name.
bucketName := "examplebucket"
// Set the full path of the object. The full path cannot contain the bucket name.
objectName := "exampleobject.txt"
// Set the full path of the local file. If you do not specify a local path, the file is uploaded from the local path that corresponds to the project of the sample program.
localFilename := "/localpath/exampleobject.txt"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Error: %v", err)
}
// Set the part size in bytes. In this example, the part size is set to 5 MB.
partSize := int64(5 * 1024 * 1024)
// Call the multipart upload function.
if err := uploadMultipart(bucket, objectName, localFilename, partSize); err != nil {
log.Fatalf("Failed to upload multipart: %v", err)
}
}
// Multipart upload function.
func uploadMultipart(bucket *oss.Bucket, objectName, localFilename string, partSize int64) error {
// Split the local file into parts.
chunks, err := oss.SplitFileByPartSize(localFilename, partSize)
if err != nil {
return fmt.Errorf("failed to split file into chunks: %w", err)
}
// Open the local file.
file, err := os.Open(localFilename)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()
// Step 1: Initialize a multipart upload event.
imur, err := bucket.InitiateMultipartUpload(objectName)
if err != nil {
return fmt.Errorf("failed to initiate multipart upload: %w", err)
}
// Step 2: Upload parts.
var parts []oss.UploadPart
for _, chunk := range chunks {
part, err := bucket.UploadPart(imur, file, chunk.Size, chunk.Number)
if err != nil {
// If a part fails to be uploaded, try to abort the multipart upload task.
if abortErr := bucket.AbortMultipartUpload(imur); abortErr != nil {
log.Printf("Failed to abort multipart upload: %v", abortErr)
}
return fmt.Errorf("failed to upload part: %w", err)
}
parts = append(parts, part)
}
// Set the access control list (ACL) of the object to private. By default, the ACL of the object is inherited from the bucket.
objectAcl := oss.ObjectACL(oss.ACLPrivate)
// Step 3: Complete the multipart upload.
_, err = bucket.CompleteMultipartUpload(imur, parts, objectAcl)
if err != nil {
// If the upload fails to be completed, try to abort the upload.
if abortErr := bucket.AbortMultipartUpload(imur); abortErr != nil {
log.Printf("Failed to abort multipart upload: %v", abortErr)
}
return fmt.Errorf("failed to complete multipart upload: %w", err)
}
log.Printf("Multipart upload completed successfully.")
return nil
}
Preguntas frecuentes
¿Cómo cancelo un evento de carga multiparte?
¿Cómo listo las partes cargadas?
Listar eventos de carga multiparte
Referencias
Para ver el código de ejemplo completo de carga multiparte, consulte Ejemplo en GitHub.
-
Una carga multiparte completa implica tres operaciones de API. Para obtener más información sobre estas operaciones, consulte los siguientes temas:
Para obtener más información sobre la operación de API utilizada para inicializar un evento de carga multiparte, consulte InitiateMultipartUpload.
Para obtener más información sobre la operación de API utilizada para cargar una parte, consulte UploadPart.
Para obtener más información sobre la operación de API utilizada para completar una carga multiparte, consulte CompleteMultipartUpload.
Para obtener más información sobre la operación de API utilizada para cancelar un evento de carga multiparte, consulte AbortMultipartUpload.
Para obtener más información sobre la operación de API utilizada para listar partes cargadas, consulte ListUploadedParts.
Para obtener más información sobre la operación de API utilizada para listar todos los eventos de carga multiparte en curso (eventos que se han iniciado pero aún no se han completado ni cancelado), consulte ListMultipartUploads.