Todos os produtos
Search
Central de documentação

Object Storage Service:Append upload

Última atualização: Jul 03, 2026

O upload por acréscimo permite adicionar conteúdo diretamente ao final de um objeto anexável existente.

Informações básicas

Objetos criados com upload simples são objetos normais, enquanto objetos gerados via upload multipartido são objetos multipartidos. Após a conclusão do upload, o conteúdo desses dois tipos de objeto torna-se fixo. Eles permitem apenas leitura e não admitem modificações. Para alterar o conteúdo, envie novamente um objeto com o mesmo nome para sobrescrever os dados existentes.

Devido a essa limitação, ao utilizar esses métodos para transmitir fluxos de vídeo em tempo real de fontes como sistemas de videomonitoramento ou ApsaraVideo Live, a única alternativa é dividir o fluxo em fragmentos menores e enviá-los continuamente como novos objetos. Essa abordagem apresenta as seguintes desvantagens:

  • A arquitetura de software torna-se complexa e exige o gerenciamento de detalhes como a fragmentação de arquivos.

  • É necessário um local para armazenar metadados, como uma lista dos objetos gerados. Consequentemente, cada requisição precisa ler repetidamente esses metadados para verificar a existência de novos objetos, o que sobrecarrega o servidor. Além disso, o cliente precisa enviar duas requisições de rede a cada vez, aumentando a latência.

  • Fragmentar objetos em partes menores reduz a latência de dados, mas a proliferação de pequenos objetos complica o gerenciamento. Por outro lado, fragmentos maiores aumentam significativamente a latência dos dados.

Para atualizar o conteúdo de um fluxo de vídeo enviado em tempo real, una o vídeo localmente e utilize o recurso de upload por acréscimo (AppendObject) do Object Storage Service (OSS). Isso cria um objeto anexável, ao qual é possível adicionar conteúdo diretamente. Os dados acrescentados tornam-se legíveis imediatamente após cada operação de acréscimo.

Benefícios

Com o upload por acréscimo, é possível enviar dados de vídeo para o mesmo objeto assim que são gerados. O cliente precisa apenas recuperar periodicamente o tamanho do objeto e compará-lo com o valor lido anteriormente. Ao detectar novos dados legíveis, o cliente inicia uma operação de leitura para obter o conteúdo recém-enviado. Esse método simplifica a arquitetura e melhora a extensibilidade.

Limites

  • Limite de tamanho

    O tamanho do objeto não pode exceder 5 GB.

  • Limites operacionais

    • Não é possível usar o upload por acréscimo para enviar objetos Cold Archive ou Deep Cold Archive.

    • O upload por acréscimo não oferece suporte a callbacks de upload.

Observações

  • Se o objeto não existir, a chamada à operação da API AppendObject cria um objeto anexável.

  • Caso o objeto já exista:

    • Se for um objeto anexável e a posição de acréscimo especificada for igual ao tamanho atual do objeto, o conteúdo será adicionado ao final dele.

    • Se for um objeto anexável, mas a posição de acréscimo especificada diferir do tamanho atual, uma exceção PositionNotEqualToLength será lançada.

    • Se for um objeto não anexável, como um objeto normal enviado via upload simples, uma exceção ObjectNotAppendable será lançada.

Métodos

Use an Alibaba Cloud SDK

As seções a seguir apresentam exemplos de código para uploads por acréscimo usando kits de desenvolvimento de software (SDKs) comuns. Para exemplos com outros SDKs, consulte Visão geral do SDK.

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.AppendObjectRequest;
import com.aliyun.oss.model.AppendObjectResult;
import com.aliyun.oss.model.ObjectMetadata;
import java.io.ByteArrayInputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // The endpoint of the China (Hangzhou) region is used as an example. Specify the actual endpoint.
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before running the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the bucket name, for example, examplebucket.
        String bucketName = "examplebucket";
        // Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt.
        String objectName = "exampledir/exampleobject.txt";
        String content1 = "Hello OSS A \n";
        String content2 = "Hello OSS B \n";
        String content3 = "Hello OSS C \n";
        // Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set Region to cn-hangzhou.
        String region = "cn-hangzhou";

        // Create an OSSClient instance.
        // When the OSSClient instance is no longer in use, 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 {
            ObjectMetadata meta = new ObjectMetadata();
            // Specify the content type of the upload.
            meta.setContentType("text/plain");
            // Specify the web page caching behavior for the object.
            //meta.setCacheControl("no-cache");
            // Specify the name of the object when it is downloaded.
            //meta.setContentDisposition("attachment;filename=oss_download.txt");
            // Specify the content encoding format of the object.
            //meta.setContentEncoding(OSSConstants.DEFAULT_CHARSET_NAME);
            // This request header is used to check whether the message content is consistent with the content sent.
            //meta.setContentMD5("ohhnqLBJFiKkPSBO1eNaUA==");
            // Specify the expiration time.
            //try {
            //    meta.setExpirationTime(DateUtil.parseRfc822Date("Wed, 08 Jul 2022 16:57:01 GMT"));
            //} catch (ParseException e) {
            //    e.printStackTrace();
            //}
            // Specify the server-side encryption method. In this example, server-side encryption with OSS-managed keys (SSE-OSS) is used.
            //meta.setServerSideEncryption(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
            // Specify the access permissions of the object. In this example, the private access permission is specified.
            //meta.setObjectAcl(CannedAccessControlList.Private);
            // Specify the storage class of the object.
            //meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
            // You can add x-oss-meta-* when you create an AppendObject. You cannot carry this parameter for subsequent appends. If you configure a parameter prefixed with x-oss-meta-*, the parameter is considered metadata.
            //meta.setHeader("x-oss-meta-author", "Alice");

            // Set multiple parameters through AppendObjectRequest.
            AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(content1.getBytes()),meta);

            // Set a single parameter through AppendObjectRequest.
            // Set the bucket name.
            //appendObjectRequest.setBucketName(bucketName);
            // Set the object name.
            //appendObjectRequest.setKey(objectName);
            // Set the content to be appended. The type can be InputStream or File. In this example, the type is InputStream.
            //appendObjectRequest.setInputStream(new ByteArrayInputStream(content1.getBytes()));
            // Set the content to be appended. The type can be InputStream or File. In this example, the type is File.
            //appendObjectRequest.setFile(new File("D:\\localpath\\examplefile.txt"));
            // Specify the metadata of the file. This is valid only for the first append.
            //appendObjectRequest.setMetadata(meta);

            // First append.
            // Set the append position of the file.
            appendObjectRequest.setPosition(0L);
            AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest);
            // The 64-bit CRC value of the file.
            System.out.println(appendObjectResult.getObjectCRC());

            // Second append.
            // nextPosition indicates the position that should be provided in the next request, which is the current length of the file.
            appendObjectRequest.setPosition(appendObjectResult.getNextPosition());
            appendObjectRequest.setInputStream(new ByteArrayInputStream(content2.getBytes()));
            appendObjectResult = ossClient.appendObject(appendObjectRequest);

            // Third append.
            appendObjectRequest.setPosition(appendObjectResult.getNextPosition());
            appendObjectRequest.setInputStream(new ByteArrayInputStream(content3.getBytes()));
            appendObjectResult = ossClient.appendObject(appendObjectRequest);
        } 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 an 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();
            }
        }
    }
}
const OSS = require('ali-oss')

const client = new OSS({
  // Set region to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set region to oss-cn-hangzhou.
  region: 'yourRegion',
  // 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.
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // Specify the bucket name. Example: examplebucket.
  bucket: 'examplebucket',
});

const headers = {    
  // Specify the access permissions of the object.
  'x-oss-object-acl': 'private',
  // Specify the storage class of the object.
  'x-oss-storage-class': 'Standard',  
  // Specify the server-side encryption method. In this example, server-side encryption with OSS-managed keys (SSE-OSS) is used.
  'x-oss-server-side-encryption': 'AES256',  
};

async function append () {
  // Perform the first append upload. The return value indicates the position for the next append operation.
  // objectName specifies the full path of the object without the bucket name. Example: destfolder/examplefile.txt.
  // localFile specifies the full path of the local file, including the file extension. Example: /users/local/examplefile.txt.
  let result = await client.append('objectName', 'localFile'
  // Custom headers and metadata.
  //,{headers} 
  )

  // Perform the second append upload. The position for the next append operation is the length of the object before this append operation (Content-Length).
  result = await client.append('objectName', 'localFile', {
    position: result.nextAppendPosition
  })
}

append();
using Aliyun.OSS;
using Aliyun.OSS.Common;

// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "yourEndpoint";
// 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. 
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// Specify the name of the bucket. Example: examplebucket. 
var bucketName = "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
var objectName = "exampledir/exampleobject.txt";
// Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. By default, if you do not specify the path of the local file, the file is uploaded from the path of the project to which the sample program belongs. 
var localFilename = "D:\\localpath\\examplefile.txt";
// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou.
const string region = "cn-hangzhou";

// Create a ClientConfiguration instance and modify the default parameters based on your requirements.
var conf = new ClientConfiguration();

// Use the signature algorithm V4.
conf.SignatureVersion = SignatureVersion.V4;

// Create an OSSClient instance.
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
c.SetRegion(region);
// The position for the first append upload is 0, and the position for the next append upload is included in the response. The position from which the next append operation starts is the current length of the object. 
long position = 0;
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    position = metadata.ContentLength;
}
catch (Exception) { }
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        // Perform the append operation. 
        var result = client.AppendObject(request);
        // Specify the position from which the append operation starts. 
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}", position);
    }
    // Query the position from which the next append operation starts and perform the second append operation. 
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        var request = new AppendObjectRequest(bucketName, objectName)
        {
            ObjectMetadata = new ObjectMetadata(),
            Content = fs,
            Position = position
        };
        var result = client.AppendObject(request);
        position = result.NextAppendPosition;
        Console.WriteLine("Append object succeeded, next append position:{0}", position);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Append object failed, {0}", ex.Message);
}
// Specify the bucket name, the full path of the object, and the full path of the local file. Example: examplebucket, exampledir/exampleobject.txt, and /storage/emulated/0/oss/examplefile.txt.
// The full path of the object cannot contain the bucket name.
AppendObjectRequest append = new AppendObjectRequest("examplebucket", "exampledir/exampleobject.txt", "/storage/emulated/0/oss/examplefile.txt");

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("text/plain");
append.setMetadata(metadata);

// Set the append position.
append.setPosition(0);

// Set the callback.
append.setProgressCallback(new OSSProgressCallback<AppendObjectRequest>() {
    @Override
    public void onProgress(AppendObjectRequest request, long currentSize, long totalSize) {
        Log.d("AppendObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});
// Asynchronously append data.
OSSAsyncTask task = oss.asyncAppendObject(append, new OSSCompletedCallback<AppendObjectRequest, AppendObjectResult>() {
    @Override
    public void onSuccess(AppendObjectRequest request, AppendObjectResult result) {
        Log.d("AppendObject", "AppendSuccess");
        Log.d("NextPosition", "" + result.getNextPosition());
    }

    @Override
    public void onFailure(AppendObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // Handle exceptions.
    }
});
OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];
// Configure the required fields. `bucketName` specifies the name of the bucket. `objectKey`, which is equivalent to `objectName`, specifies the full path of the object to which you want to append data. The path must include the file extension, for example, `abc/efg/123.jpg`.
append.bucketName = @"<bucketName>";
append.objectKey = @"<objectKey>";
// Specify the position for the first append upload.
append.appendPosition = 0; 
NSString * docDir = [self getDocumentDirectory];
append.uploadingFileURL = [NSURL fileURLWithPath:@"<yourLocalFilePath>"];
// The following fields are optional.
append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
    NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
// append.contentType = @"";
// append.contentMd5 = @"";
// append.contentEncoding = @"";
// append.contentDisposition = @"";
OSSTask * appendTask = [client appendObject:append];
[appendTask continueWithBlock:^id(OSSTask *task) {
    NSLog(@"objectKey: %@", append.objectKey);
    if (!task.error) {
        NSLog(@"append object success!");
        OSSAppendObjectResult * result = task.result;
        NSString * etag = result.eTag;
        long nextPosition = result.xOssNextAppendPosition;
    } else {
        NSLog(@"append object failed, error: %@" , task.error);
    }
    return nil;
}];
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the OSS account information. */
            
    /* Set yourEndpoint to the Endpoint of the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the Endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Set yourRegion to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the Region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the bucket name, for example, examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. For example, exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* Initialize network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* Obtain access credentials from environment variables. Before running this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    auto meta = ObjectMetaData();
    meta.setContentType("text/plain");

    /* The position for the first append operation is 0. The return value indicates the position for the next append operation. The position for subsequent append operations is the length of the object before the append. */
    std::shared_ptr<std::iostream> content1 = std::make_shared<std::stringstream>();
    *content1 <<"Thank you for using Alibaba Cloud Object Storage Service!";
    AppendObjectRequest request(BucketName, ObjectName, content1, meta);
    request.setPosition(0L);

    /* Append data to the object for the first time. */
    auto result = client.AppendObject(request);

    if (!result.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "AppendObject fail" <<
        ",code:" << result.error().Code() <<
        ",message:" << result.error().Message() <<
        ",requestId:" << result.error().RequestId() << std::endl;
        return -1;
    }

    std::shared_ptr<std::iostream> content2 = std::make_shared<std::stringstream>();
    *content2 <<"Thank you for using Alibaba Cloud Object Storage Service!";
    auto position = result.result().Length();
    AppendObjectRequest appendObjectRequest(BucketName, ObjectName, content2);
    appendObjectRequest.setPosition(position);

    /* Append data to the object for the second time. */
    auto outcome = client.AppendObject(appendObjectRequest);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "AppendObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* Release network resources. */
    ShutdownSdk();
    return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
/* Set yourEndpoint to the Endpoint of the region where the bucket is located. For example, for the China (Hangzhou) region, set the Endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
const char *endpoint = "yourEndpoint";

/* Specify the bucket name. For example, examplebucket. */
const char *bucket_name = "examplebucket";
/* Specify the full path of the object. The full path cannot contain the bucket name. For example, exampledir/exampleobject.txt. */
const char *object_name = "exampledir/exampleobject.txt";
const char *object_content = "More than just cloud.";
/* Set yourRegion to the region where the bucket is located. For example, for the China (Hangzhou) region, set the region to cn-hangzhou. */
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* Initialize the aos_string_t type with a char* string. */
    aos_str_set(&options->config->endpoint, endpoint);
    /* Obtain access credentials from environment variables. Before running this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. */    
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    // Configure the following two parameters.
    aos_str_set(&options->config->region, region);
    options->config->signature_version = 4;
    /* Specifies whether a CNAME is used. 0 indicates that a CNAME is not used. */
    options->config->is_cname = 0;
    /* Set network parameters, such as the timeout period. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* Call the aos_http_io_initialize method at the program entry to initialize global resources, such as the network and memory. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* The memory pool for memory management is equivalent to apr_pool_t. The implementation code is in the apr library. */
    aos_pool_t *pool;
    /* Create a new memory pool. The second parameter is NULL, which indicates that the new memory pool does not inherit from another memory pool. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter includes global configuration information such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate memory to options in the memory pool. */
    oss_client_options = oss_request_options_create(pool);
    /* Initialize the client options oss_client_options. */
    init_options(oss_client_options);
    /* Initialize parameters. */
    aos_string_t bucket;
    aos_string_t object;
    aos_list_t buffer;
    int64_t position = 0;
    char *next_append_position = NULL;
    aos_buf_t *content = NULL;
    aos_table_t *headers1 = NULL;
    aos_table_t *headers2 = NULL;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL; 
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    headers1 = aos_table_make(pool, 0);
    /* Get the starting append position. */
    resp_status = oss_head_object(oss_client_options, &bucket, &object, headers1, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        next_append_position = (char*)(apr_table_get(resp_headers, "x-oss-next-append-position"));
        position = atoi(next_append_position);
    }
    /* Append the object. */
    headers2 = aos_table_make(pool, 0);
    aos_list_init(&buffer);
    content = aos_buf_pack(pool, object_content, strlen(object_content));
    aos_list_add_tail(&content->node, &buffer);
    resp_status = oss_append_object_from_buffer(oss_client_options, &bucket, &object, position, &buffer, headers2, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        printf("append object from buffer succeeded\n");
    } else {
        printf("append object from buffer failed\n");
    }
    /* Release the memory pool. This releases the memory allocated to resources during the request. */
    aos_pool_destroy(pool);
    /* Release the previously allocated global resources. */
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  # The China (Hangzhou) region is used as an example. Specify the actual region.
  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 set.
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)

# Specify the bucket name, for example, examplebucket.
bucket = client.get_bucket('examplebucket')
# Specify the full path of the object. The full path cannot contain the bucket name.
bucket.append_object('my-object', 0)

# Append content to the end of the file.
next_pos = bucket.append_object('my-object', 0) do |stream|
  100.times { |i| stream << i.to_s }
end
next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-1')
next_pos = bucket.append_object('my-object', next_pos, :file => 'local-file-2')
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)
}
import argparse
import alibabacloud_oss_v2 as oss

# Create a command-line argument parser.
parser = argparse.ArgumentParser(description="append object sample")

# Add command-line arguments.
# --region: Specifies the region where the OSS bucket is located.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# --bucket: Specifies the name of the bucket to operate on.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# --endpoint: An optional parameter that specifies the domain name used to access the OSS service.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# --key: Specifies the key of the object (file) in OSS.
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # Parse the command-line arguments.
    args = parser.parse_args()

    # Load the authentication information required for OSS from environment variables.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Create a configuration object using the default configurations provided by the SDK.
    cfg = oss.config.load_default()

    # Set the credential provider to the previously created object.
    cfg.credentials_provider = credentials_provider

    # Set the region for the OSS client based on user input.
    cfg.region = args.region

    # If the user provides a custom endpoint, update the configuration.
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # Create an OSS client instance using the preceding configurations.
    client = oss.Client(cfg)

    # Define the data to be appended.
    data1 = b'hello'
    data2 = b' world'

    # Append data for the first time.
    result = client.append_object(oss.AppendObjectRequest(
        bucket=args.bucket,  # Specify the destination bucket.
        key=args.key,  # Specify the key of the object.
        position=0,  # The starting position for appending, which is initially 0.
        body=data1,  # The data to be appended.
    ))

    # Print the result of the first append operation.
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' version id: {result.version_id},'
          f' hash crc64: {result.hash_crc64},'
          f' next position: {result.next_position},' 
    )

    # Append data for the second time.
    result = client.append_object(oss.AppendObjectRequest(
        bucket=args.bucket,  # Specify the destination bucket.
        key=args.key,  # Specify the key of the object.
        position=result.next_position,  # Start from the next position of the previous append operation.
        body=data2,  # The data to be appended.
    ))

    # Print the result of the second append operation.
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' version id: {result.version_id},'
          f' hash crc64: {result.hash_crc64},'
          f' next position: {result.next_position},'
    )

# When this script is run directly, call the main function.
if __name__ == "__main__":
    main()
<?php

// Introduce autoload files to load dependency libraries.
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// Define and describe command-line parameters.
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // (Required) Specify the region in which the bucket is located.
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // (Optional) Specify the endpoint for accessing OSS.
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // (Required) Specify the name of the bucket.
    "key" => ['help' => 'The name of the object', 'required' => True], // (Required) Specify the name of the object.
];

// Convert the descriptions to a list of long options required by getopt.
// Add a colon (:) to the end of each parameter to indicate that a value is required.
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// Parse the command-line parameters.
$options = getopt("", $longopts);

// Check whether the required parameters are configured.
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // Obtain help information for the parameters.
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // Exit the program if a required parameter is missing.
    }
}

// Assign the values parsed from the command-line parameters to the corresponding variables.
$region = $options["region"]; // The region in which the bucket is located.
$bucket = $options["bucket"]; // The name of the bucket.
$key = $options["key"];       // The name of the object.

// Load access credentials from environment variables.
// Use EnvironmentVariableCredentialsProvider to retrieve the AccessKey ID and AccessKey secret from environment variables.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// Use the default configuration of the SDK.
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // Specify the credential provider.
$cfg->setRegion($region); // Specify the region in which the bucket is located.
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // Specify the endpoint if one is provided.
}

// Create an OSSClient instance.
$client = new Oss\Client($cfg);

// Specify the content that you want to append.
$data='Hello Append Object'; // Replace the sample data with your actual content.

// Create an AppendObjectRequest object to append data to a specific object.
$request = new Oss\Models\AppendObjectRequest(bucket: $bucket, key: $key);
$request->body = Oss\Utils::streamFor($data); // Specify that the HTTP request body is a binary stream.
$request->position = 0; // Set the position from which the first append operation starts to 0.

// Perform the append upload operation.
$result = $client->appendObject($request);

// Display the result.
// Display the HTTP status code and the request ID to check whether the request succeeded.
printf(
    'status code:' . $result->statusCode . PHP_EOL . // The HTTP status code. For example, HTTP status code 200 indicates that the request succeeded.
    'request id:' . $result->requestId . PHP_EOL .    // The request ID, which is used to debug or trace a request.
    'next append position:' . $result->nextPosition . PHP_EOL // Specify the position from which the next append operation starts.
);

Use the ossutil command line interface

Use a interface de linha de comando (CLI) ossutil para acrescentar e enviar objetos. Para instalar o ossutil, consulte Instalar o ossutil.

O comando a seguir acrescenta conteúdo ao objeto exampleobject como uma string.

ossutil api append-object --bucket examplebucket --key exampleobject --position 0 --body "hi oss"

Para mais informações sobre este comando, consulte append-object.

Operações de API relacionadas

Os métodos anteriores baseiam-se em operações de API. Caso seu programa exija alto nível de personalização, envie requisições REST API diretamente. Para isso, escreva manualmente o código para calcular as assinaturas. Para mais informações, consulte AppendObject.

Perguntas frequentes

Existem restrições de tipo de arquivo para o upload por acréscimo?

Não. O upload por acréscimo reconhece apenas fluxos binários e não impõe requisitos quanto aos tipos de arquivo.

Após acrescentar vários vídeos, por que o tamanho total do vídeo combinado é igual à soma dos arquivos individuais, mas o vídeo combinado contém apenas o conteúdo do primeiro vídeo acrescentado?

  • Causa

    Arquivos de vídeo possuem uma estrutura complexa que inclui cabeçalhos de metadados, índices e outros conteúdos estruturados. Essas informações indicam dados como duração total, codec e taxa de quadros do vídeo. Ao acrescentar diretamente vários clipes, os metadados do vídeo original não são atualizados automaticamente para acomodar o novo conteúdo. Como resultado, o arquivo de vídeo combinado torna-se apenas uma concatenação de fluxos de bytes, impedindo a análise correta do conteúdo.

  • Solução

    Utilize o OSS em conjunto com o recurso de união de vídeos do Intelligent Media Management (IMM) para mesclar os vídeos. Para mais informações, consulte União de vídeos.

Como converter um arquivo não anexável em um arquivo anexável?

O OSS não suporta a conversão direta de um objeto não anexável para anexável. No entanto, você pode realizar a conversão seguindo o método abaixo:

  1. Utilize a operação da API AppendObject para criar um novo objeto anexável vazio.

  2. Baixe o objeto original e leia seu conteúdo.

  3. Use a operação da API AppendObject para acrescentar o conteúdo ao objeto recém-criado.

Importante

O processo de conversão envolve a releitura e o reenvio do conteúdo. Após concluir a conversão, verifique a disponibilidade do objeto.