O Object Storage Service (OSS) oferece um recurso de multipart upload para objetos grandes. Esse processo divide o objeto em partes menores, envia cada parte independentemente e chama a API CompleteMultipartUpload para combiná-las em um único objeto, permitindo uploads retomáveis.
Observações
Este tópico utiliza o endpoint público da região China (Hangzhou). Para acessar o OSS a partir de outros serviços da Alibaba Cloud na mesma região, use um endpoint interno. Para obter mais informações sobre regiões e endpoints do OSS, consulte Regiões e endpoints.
As credenciais de acesso neste tópico são obtidas de variáveis de ambiente. Para saber como configurar credenciais de acesso, consulte Configurar credenciais de acesso.
Este tópico demonstra a criação de uma instância OSSClient com um endpoint do OSS. Para configurações alternativas, como uso de domínio personalizado ou autenticação com credenciais do Security Token Service (STS), consulte Configurar um cliente (Go SDK V1).
O multipart upload utiliza InitiateMultipartUpload, UploadPart e CompleteMultipartUpload. É necessário ter a permissão
oss:PutObject. Consulte Conceder políticas de acesso personalizadas a um usuário RAM.O código de exemplo deste tópico requer o Go SDK V2.2.5 ou posterior.
Procedimento de multipart upload
O multipart upload envolve três etapas:
-
Inicialize um multipart upload.
Chame o método Bucket.InitiateMultipartUpload. O OSS retorna um ID de upload globalmente exclusivo.
-
Envie as partes.
Chame o método Bucket.UploadPart para enviar os dados de cada parte.
NotaPara o mesmo ID de upload, o número da parte identifica sua posição relativa dentro do objeto. Se você enviar novos dados usando o mesmo número de parte, os dados existentes dessa parte no OSS serão sobrescritos.
O OSS retorna o hash MD5 dos dados da parte recebida no cabeçalho ETag.
O OSS calcula o hash MD5 dos dados enviados e o compara com o hash MD5 calculado pelo SDK. Se os dois hashes MD5 não coincidirem, o sistema retornará o código de erro InvalidDigest.
-
Conclua o multipart upload.
Após enviar todas as partes, chame o método Bucket.CompleteMultipartUpload para combiná-las em um objeto completo.
Código de exemplo
Use o código a seguir para executar um multipart upload completo.
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
}
Perguntas frequentes
Como cancelar um evento de multipart upload?
Como listar as partes enviadas?
Listar eventos de multipart upload
Referências
Para obter o código de exemplo completo de multipart upload, consulte o exemplo no GitHub.
-
Um multipart upload completo envolve três operações de API. Para obter mais informações sobre essas operações, consulte os tópicos a seguir:
Para detalhes sobre a operação de API usada para inicializar um evento de multipart upload, consulte InitiateMultipartUpload.
Para detalhes sobre a operação de API usada para enviar uma parte, consulte UploadPart.
Para detalhes sobre a operação de API usada para concluir um multipart upload, consulte CompleteMultipartUpload.
Para detalhes sobre a operação de API usada para cancelar um evento de multipart upload, consulte AbortMultipartUpload.
Para detalhes sobre a operação de API usada para listar partes enviadas, consulte ListUploadedParts.
Para detalhes sobre a operação de API usada para listar todos os eventos de multipart upload em andamento (eventos iniciados, mas ainda não concluídos ou cancelados), consulte ListMultipartUploads.