Todos os produtos
Search
Central de documentação

Object Storage Service:Upload por append (Go SDK V2)

Última atualização: Sep 25, 2026

O upload por append permite acrescentar conteúdo diretamente ao final de um objeto appendable existente. Este tópico descreve como fazer upload por append usando o OSS SDK for Go.

Notas de uso

  • O código de exemplo neste tópico usa o ID de região cn-hangzhou para a região china (Hangzhou). Por padrão, o acesso a recursos em um bucket utiliza o endpoint público. Para acessar recursos no bucket por meio de outros serviços da Alibaba Cloud na mesma região do bucket, use o endpoint interno. Para obter mais informações sobre as regiões e endpoints do OSS, consulte Regions and endpoints.

  • Neste tópico, o exemplo lê as credenciais de acesso a partir de variáveis de ambiente. Para obter mais informações sobre como configure as credenciais de acesso, consulte Configure access credentials.

  • Se o arquivo ao qual você deseja acrescentar conteúdo não existir, a API de upload por append crie um objeto appendable.

  • Se o arquivo ao qual você deseja acrescentar conteúdo já existir:

    • Se o arquivo for um objeto appendable e a posição de append que você especifique for igual ao tamanho atual do arquivo, o sistema acrescenta o conteúdo ao final do arquivo.

    • Se o arquivo for um objeto appendable, mas a posição de append que você especifique for diferente do tamanho atual do arquivo, ocorre a exceção PositionNotEqualToLength.

    • Se o arquivo não for um objeto appendable, como um objeto normal enviado por meio de upload simples, ocorre a exceção ObjectNotAppendable.

Permissões

Por padrão, uma conta Alibaba Cloud tem permissões completas. Usuários RAM ou funções RAM sob uma conta Alibaba Cloud não têm permissões por padrão. A conta Alibaba Cloud ou o administrador da conta deve conceder as permissões de operação por meio de RAM policies ou Bucket Policy.

API

Ação

Descrição

AppendObject

oss:PutObject

Use esta operação para fazer upload de um objeto adicionando-o a um objeto existente.

oss:PutObjectTagging

Ao fazer upload de um objeto adicionando-o a um objeto existente, se você especifique tags de objeto por meio de x-oss-tagging, essa permissão é obrigatória.

Definição do método

Para cenários de upload por append, o OSS SDK for Go fornece a nova operação AppendFile para simular comportamentos de leitura e gravação de arquivo de objetos em um bucket. A tabela a seguir descreve as operações AppendFile e AppendObject.

Nome da operação

Descrição

Client.AppendObject

Executa um upload por append. O objeto final pode ter até 5 GiB.

Suporta a verificação de integridade de dados CRC-64 (ativada por padrão).

Suporta barras de progresso.

O corpo da requisição é do tipo io.Reader. Se o tipo io.Seeker for compatível, a retransmissão fica disponível em caso de falha. Essa operação não é idempotente e a retransmissão pode falhar.

Client.AppendFile

Oferece os mesmos recursos da operação Client.AppendObject.

Otimiza a tolerância a falhas em caso de erros de retransmissão.

Inclui a operação AppendOnlyFile.

AppendOnlyFile.Write

AppendOnlyFile.WriteFrom

API premium de upload por append: AppendFile

Use a operação AppendFile para fazer upload de dados por append. Se o objeto não existir, o OSS crie um objeto appendable. Se o objeto existir, mas não for um objeto appendable, o OSS retorna um erro.

O código de exemplo a seguir mostra como definir a operação AppendFile.

type AppendOnlyFile struct {
...
}

func (c *Client) AppendFile(ctx context.Context, bucket string, key string, optFns ...func(*AppendOptions)) (*AppendOnlyFile, error)

Parâmetros da requisição

Parâmetro

Tipo

Descrição

ctx

context.Context

O contexto da requisição.

bucket

string

O nome do bucket.

key

string

O nome do objeto.

optFns

...func(*AppendOptions)

Opcional. As opções de configuração para adicionar um arquivo.

A tabela a seguir descreve os parâmetros de AppendOptions.

Parâmetro

Tipo

Descrição

RequestPayer

*string

Se o modo de pagamento por solicitante estiver ativado, defina este parâmetro como 'requester'.

CreateParameter

*AppendObjectRequest

Usado para definir os metadados de um objeto durante o primeiro upload. Os metadados incluem ContentType, Metadata, permissões e classe de armazenamento. Para obter mais informações, consulte AppendObjectRequest.

Valores de retorno

Valor de retorno

Tipo

Descrição

file

*AppendOnlyFile

A instância do arquivo appendable. Este parâmetro é válido apenas quando err é nil. Para obter mais informações, consulte AppendOnlyFile.

err

error

O status de abertura do arquivo appendable. Se a operação falhar, err não será nil.

A tabela a seguir descreve a operação AppendOnlyFile.

Nome da operação

Descrição

Close() error

Fecha o handle do arquivo para liberar recursos.

Write(b []byte) (int, error)

Grava os dados de b no fluxo de dados e retorna o número de bytes gravados e eventuais erros.

WriteFrom(r io.Reader) (int64, error)

Grava os dados de r no fluxo de dados e retorna o número de bytes gravados e eventuais erros.

Stat() (os.FileInfo, error)

Obtém as informações do objeto, incluindo o tamanho do objeto, o horário da última modificação e os metadados.

API básica de upload por append: AppendObject

func (c *Client) AppendObject(ctx context.Context, request *AppendObjectRequest, optFns ...func(*Options)) (*AppendObjectResult, error)

Parâmetros da requisição

Parâmetro

Tipo

Descrição

ctx

context.Context

O contexto da requisição, que permite definir o tempo limite total da requisição.

request

*AppendObjectRequest

Os parâmetros da requisição para uma operação de API específica. Para obter mais informações, consulte AppendObjectRequest.

optFns

...func(*Options)

Opcional. Os parâmetros de configuração no nível de operação. Para obter mais informações, consulte Options.

Valores de retorno

Valor de retorno

Tipo

Descrição

result

*AppendObjectResult

O valor de retorno da operação de API. Este parâmetro é válido apenas quando err é nil. Para obter mais informações, consulte AppendObjectResult.

err

error

O status da requisição. Se a requisição falhar, err não será nil.

Código de exemplo

Use AppendFile para fazer upload por append

package main

import (
	"context"
	"flag"
	"log"
	"os"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define global variables.
var (
	region     string // The storage region.
	bucketName string // The bucket name.
	objectName string // The object name.
)

// The init function is used to initialize command-line parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// Parse command-line parameters.
	flag.Parse()

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the storage region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Configure the OSS client.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Create an instance of an appendable file.
	f, err := client.AppendFile(context.TODO(),
		bucketName,
		objectName,
		func(ao *oss.AppendOptions) {
			ao.CreateParameter = &oss.AppendObjectRequest{
				Acl: oss.ObjectACLPrivate, // Set the access permissions of the object to private.
				Metadata: map[string]string{
					"user": "jack", // Set the metadata of the object.
				},
				Tagging: oss.Ptr("key=value"), // Set the tags for the object.
			}
		})

	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	defer f.Close() // Make sure that the data stream is closed when the function ends.

	// Open the local file example1.txt.
	lf, err := os.Open("/local/dir/example1.txt")
	if err != nil {
		log.Fatalf("failed to open local file %v", err)
	}

	// Append the content of example1.txt to the OSS object.
	_, err = f.WriteFrom(lf)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	lf.Close() // Close the local file.

	// Open the local file example2.txt.
	lf, err = os.Open("/local/dir/example2.txt")
	if err != nil {
		log.Fatalf("failed to open local file %v", err)
	}

	// Append the content of example2.txt to the OSS object.
	_, err = f.WriteFrom(lf)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	lf.Close() // Close the local file.

	// Read the content of the local file example3.txt.
	lb, err := os.ReadFile("/local/dir/example3.txt")
	if err != nil {
		log.Fatalf("failed to read local file %v", err)
	}

	// Append the content of example3.txt to the OSS object.
	_, err = f.Write(lb)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}

	// Print the log information about the successful append upload.
	log.Printf("append file successfully")
}

Use AppendObject para fazer upload por append

package main

import (
	"context"
	"flag"
	"log"
	"strings"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define global variables.
var (
	region     string
	bucketName string
	objectName string
)

// The init function is used to initialize command-line parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// Parse command-line parameters.
	flag.Parse()

	// Define the initial position for the append upload.
	var (
		position = int64(0)
	)

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and set the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Define the content to append.
	content := "hi append object"

	// Create an AppendObject request.
	request := &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(position),
		Body:     strings.NewReader(content),
	}

	// Execute the AppendObject request and process the result.
	// The position for the first append upload is 0. The return value contains the position for the next append upload.
	result, err := client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// Create the second AppendObject request.
	request = &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(result.NextPosition), // Obtain NextPosition from the return value of the first AppendObject request.
		Body:     strings.NewReader("hi append object"),
	}

	// Execute the second AppendObject request and process the result.
	result, err = client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	log.Printf("append object result:%#v\n", result)
}

Cenários comuns

Faça upload por append e exiba uma barra de progresso

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"strings"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// Define global variables.
var (
	region     string
	bucketName string
	objectName string
)

// The init function is used to initialize command-line parameters.
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// Parse command-line parameters.
	flag.Parse()

	// Define the initial position for the append upload.
	var (
		position = int64(0)
	)

	// Check whether the bucket name is empty.
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// Check whether the region is empty.
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// Check whether the object name is empty.
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// Load the default configurations and set the credential provider and region.
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// Create an OSS client.
	client := oss.NewClient(cfg)

	// Define the content to append.
	content := "hi append object"

	// Create an AppendObject request.
	request := &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(position),
		Body:     strings.NewReader(content),
		ProgressFn: func(increment, transferred, total int64) {
			fmt.Printf("increment:%v, transferred:%v, total:%v\n", increment, transferred, total)
		}, // The progress callback function, which is used to display the upload progress.
	}

	// Execute the first AppendObject request and process the result.
	// The position for the first append upload is 0. The return value contains the position for the next append upload.
	result, err := client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// Create the second AppendObject request.
	request = &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(result.NextPosition), // Obtain NextPosition from the return value of the first AppendObject request.
		Body:     strings.NewReader("hi append object"),
		ProgressFn: func(increment, transferred, total int64) {
			fmt.Printf("increment:%v, transferred:%v, total:%v\n", increment, transferred, total)
		}, // The progress callback function, which is used to display the upload progress.
	}

	// Execute the second AppendObject request and process the result.
	result, err = client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// Print the versionId of the appended object.
	log.Printf("append object result:%#v\n", *result.VersionId)
}

Referências

  • Para obter o código de exemplo completo para upload por append, consulte os exemplos do GitHub e o Guia do Desenvolvedor.

  • Para obter mais informações sobre a operação de API premium para upload por append, consulte AppendFile.

  • Para obter mais informações sobre a operação de API básica para upload por append, consulte AppendObject.