Todos os produtos
Search
Central de documentação

Object Storage Service:Multipart upload (Go SDK V1)

Última atualização: Jul 03, 2026

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:

  1. Inicialize um multipart upload.

    Chame o método Bucket.InitiateMultipartUpload. O OSS retorna um ID de upload globalmente exclusivo.

  2. Envie as partes.

    Chame o método Bucket.UploadPart para enviar os dados de cada parte.

    Nota
    • Para 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.

  3. 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?

Use o método Bucket.AbortMultipartUpload para cancelar um evento de multipart upload nos cenários a seguir.

  1. Erro no arquivo:

    • Caso identifique que um arquivo está corrompido ou contém código malicioso durante o upload, cancele a operação para evitar ameaças potenciais.

  2. Rede instável:

    • Se a conexão de rede estiver instável ou for interrompida, partes podem ser perdidas ou corrompidas durante o upload. Cancele e reinicie o upload para garantir a integridade e a consistência dos dados.

  3. Limites de recursos:

    • Quando o espaço de armazenamento for limitado e o arquivo a ser enviado for muito grande, cancele o upload para liberar recursos de armazenamento. Isso permite alocar recursos para tarefas mais importantes.

  4. Operação acidental:

    • Se você iniciar acidentalmente uma tarefa de upload desnecessária ou enviar uma versão incorreta do arquivo, cancele o evento de upload.

...
if err = bucket.AbortMultipartUpload(imur); err != nil {
log.Fatalf("failed to abort multipart upload: %w", err)
}

log.Printf("Multipart upload aborted successfully.")

Como listar as partes enviadas?

Use o método Bucket.ListUploadedParts para listar as partes enviadas com sucesso em um evento específico de multipart upload nos cenários abaixo.

Monitorar o progresso do upload:

  1. Uploads de arquivos grandes:

    • Ao enviar um arquivo grande, liste as partes já carregadas para confirmar que o upload está progredindo conforme o esperado e identificar problemas rapidamente.

  2. Uploads retomáveis:

    • Se a rede estiver instável ou o upload for interrompido, visualize as partes já enviadas para decidir se deve tentar enviar as partes restantes. Isso ajuda a retomar o upload.

  3. Solução de problemas:

    • Caso ocorra um erro durante o upload, verifique as partes enviadas para localizar rapidamente a origem do problema. Por exemplo, se uma parte específica falhar ao ser enviada, resolva a questão adequadamente.

  4. Gerenciamento de recursos:

    • Em cenários que exigem controle rigoroso do uso de recursos, monitore o progresso do upload para gerenciar melhor o espaço de armazenamento e a largura de banda. Isso garante uma utilização eficiente dos recursos.

...	
if lsRes, err := bucket.ListUploadedParts(imur); err != nil {
log.Fatalf("Failed to list uploaded parts: %v", err)
}

for _, upload := range lsRes.UploadedParts {
log.Printf("List PartNumber: %d, ETag: %s, LastModified: %v\n", upload.PartNumber, upload.ETag, upload.LastModified)
}

Listar eventos de multipart upload

Use o método Bucket.ListMultipartUploads para listar todos os eventos de multipart upload em andamento em um bucket nas situações descritas a seguir.

Cenários de monitoramento:

  1. Gerenciamento de upload em lote de arquivos:

    • Quando precisar enviar muitos arquivos, use o método ListMultipartUploads para monitorar todas as atividades de multipart upload em tempo real. Isso assegura que todos os arquivos sejam corretamente enviados em partes.

  2. Detecção e recuperação de falhas:

    • Se ocorrerem problemas de rede ou outras falhas durante o upload, algumas partes podem não ser enviadas. Ao monitorar os eventos de multipart upload em andamento, é possível detectar esses problemas prontamente e tomar medidas para retomar os uploads.

  3. Otimização e gerenciamento de recursos:

    • Durante uploads de arquivos em grande escala, monitorar eventos de multipart upload em andamento ajuda a otimizar a alocação de recursos. Por exemplo, ajuste o uso de largura de banda ou otimize a política de upload com base no progresso.

  4. Migração de dados:

    • Ao executar um projeto de migração de dados em grande escala, monitore todos os eventos de multipart upload em andamento para garantir o bom andamento da tarefa de migração. Isso permite detectar e resolver quaisquer problemas potenciais rapidamente.

Configurações de parâmetros

Parâmetro

Descrição

Delimiter

Caractere usado para agrupar nomes de objetos. Todos os nomes de objetos que contêm o prefixo especificado e aparecem antes da primeira ocorrência do caractere delimitador são agrupados como um único elemento.

MaxUploads

Número máximo de eventos de multipart upload a serem retornados. O valor padrão e o valor máximo são ambos 1000.

KeyMarker

Eventos de multipart upload cujos nomes de objetos são lexicograficamente maiores que o valor do parâmetro KeyMarker. Use este parâmetro junto com o parâmetro UploadIDMarker para especificar a posição inicial dos resultados a serem retornados.

Prefix

Prefixo que os nomes dos objetos retornados devem conter. Observe que, se você usar o parâmetro Prefix em uma consulta, os nomes dos objetos retornados ainda conterão o prefixo.

UploadIDMarker

Posição inicial dos resultados a serem retornados. Este parâmetro é usado em conjunto com o parâmetro KeyMarker.

  • Se o parâmetro KeyMarker não estiver definido, o OSS ignora este parâmetro.

  • Se o parâmetro KeyMarker estiver definido, os resultados da consulta incluem o seguinte:

    • Eventos de multipart upload cujos nomes de objetos são lexicograficamente maiores que o valor do parâmetro KeyMarker.

    • Eventos de multipart upload cujos nomes de objetos são iguais ao valor do parâmetro KeyMarker, mas cujos IDs de upload são maiores que o valor do parâmetro UploadIDMarker.

  • Use os parâmetros padrão.

    ...
    lsRes, err := bucket.ListMultipartUploads(oss.KeyMarker(keyMarker), oss.UploadIDMarker(uploadIdMarker))
    if err != nil {
    log.Fatalf("failed to list multipart uploads: %w", err)
    }
    
    for _, upload := range lsRes.Uploads {
    log.Printf("Upload: %s, UploadID: %s\n", upload.Key, upload.UploadID)
    }
  • Especifique o prefixo como file.

    ...
    lsRes, err := bucket.ListMultipartUploads(oss.Prefix('file'))
    if err != nil {
    log.Fatalf("failed to list multipart uploads with prefix: %w", err)
    }
    
    log.Printf("Uploads:", lsRes.Uploads)
  • Defina o retorno de no máximo 100 resultados.

    ...
    lsRes, err := bucket.ListMultipartUploads(oss.MaxUploads(100))
    if err != nil {
    log.Fatalf("failed to list multipart uploads with limit: %w", err)
    }
    
    log.Printf("Uploads:", lsRes.Uploads)
  • Especifique o prefixo como file e limite o retorno a 100 resultados.

    ...
    lsRes, err := bucket.ListMultipartUploads(oss.Prefix("file"), oss.MaxUploads(100))
    if err != nil {
    log.Fatalf("failed to list multipart uploads with prefix and limit: %w", err)
    }
    
    log.Printf("Uploads:", lsRes.Uploads)

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.