Le téléchargement par ajout permet d'ajouter du contenu directement à la fin d'un objet existant de type « ajoutable ».
Contexte
Les objets créés via un téléchargement simple sont des objets normaux, tandis que ceux créés via un téléchargement en plusieurs parties sont des objets multiparties. Une fois le téléchargement terminé, le contenu de ces deux types d'objets est figé : vous ne pouvez que les lire, sans pouvoir les modifier. Si le contenu de l'objet change, vous devez télécharger à nouveau un objet portant le même nom pour écraser le contenu existant.
Cette limitation vous contraint, lors du téléchargement de flux vidéo en temps réel (provenant par exemple de systèmes de vidéosurveillance ou d'ApsaraVideo Live), à découper le flux en fragments et à les télécharger continuellement sous forme de nouveaux objets. Cette approche présente les inconvénients suivants :
L'architecture logicielle devient complexe, car vous devez gérer des détails tels que le découpage des fichiers.
Vous devez stocker les métadonnées, par exemple dans une liste des objets générés. Chaque requête doit alors lire ces métadonnées pour vérifier l'apparition de nouveaux objets, ce qui alourdit considérablement la charge du serveur. Le client doit également envoyer deux requêtes réseau à chaque fois, ce qui peut augmenter la latence.
Le découpage des objets en petits fragments réduit la latence des données, mais rend la gestion complexe en raison du grand nombre d'objets. À l'inverse, un découpage en fragments plus grands augmente significativement la latence des données.
Pour mettre à jour le contenu d'un flux vidéo téléchargé en temps réel, assemblez d'abord la vidéo localement, puis téléchargez-la à l'aide de la fonctionnalité de téléchargement par ajout (AppendObject) fournie par Object Storage Service (OSS). Cela crée un objet de type « ajoutable ». Vous pouvez ajouter directement du contenu à cet objet. Les données ajoutées sont lisibles immédiatement après chaque opération d'ajout.
Avantages
Avec le téléchargement par ajout, chargez les données vidéo dans le même objet dès leur génération. Le client récupère périodiquement la longueur de l'objet et la compare à la longueur précédemment lue. Si de nouvelles données lisibles sont détectées, le client déclenche une opération de lecture pour récupérer les données nouvellement téléchargées. Cette méthode simplifie l'architecture et améliore l'extensibilité.
Limites
-
Limite de taille
La taille de l'objet ne peut pas dépasser 5 Go.
-
Limites opérationnelles
Vous ne pouvez pas utiliser le téléchargement par ajout pour les objets Cold Archive ou Deep Cold Archive.
Le téléchargement par ajout ne prend pas en charge les callbacks de téléchargement.
Notes
Si l'objet n'existe pas, l'appel de l'opération API AppendObject crée un objet de type « ajoutable ».
-
Si l'objet existe déjà :
Si l'objet est de type « ajoutable » et que la position d'ajout spécifiée est égale à la longueur actuelle de l'objet, le contenu est ajouté à la fin de l'objet.
Si l'objet est de type « ajoutable », mais que la position d'ajout spécifiée n'est pas égale à la longueur actuelle de l'objet, une exception PositionNotEqualToLength est levée.
Si l'objet n'est pas de type « ajoutable » (par exemple, un objet normal téléchargé via un téléchargement simple), une exception ObjectNotAppendable est levée.
Méthodes
Utiliser un SDK Alibaba Cloud
Les sections suivantes fournissent des exemples de code pour les téléchargements par ajout à l'aide des kits de développement logiciel (SDK) courants. Pour des exemples de code utilisant d'autres SDK, consultez la vue d'ensemble des 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(®ion, "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.
);
Utiliser l'interface de ligne de commande ossutil
Utilisez l'interface de ligne de commande (CLI) ossutil pour ajouter et télécharger des objets. Pour installer ossutil, consultez la section Installer ossutil.
La commande suivante ajoute du contenu à l'objet exampleobject sous forme de chaîne.
ossutil api append-object --bucket examplebucket --key exampleobject --position 0 --body "hi oss"
Pour plus d'informations sur cette commande, consultez la section append-object.
Opérations API associées
Les méthodes précédentes s'appuient sur des opérations API. Si votre programme exige un haut degré de personnalisation, envoyez directement des requêtes REST API. Pour ce faire, vous devez écrire manuellement le code permettant de calculer les signatures. Pour plus d'informations, consultez la section AppendObject.
FAQ
Existe-t-il des restrictions de type de fichier pour le téléchargement par ajout ?
Non. Le téléchargement par ajout ne reconnaît que les flux binaires et n'impose aucune exigence concernant les types de fichiers.
Comment convertir un fichier non ajoutable en fichier ajoutable ?
OSS ne prend pas en charge la conversion directe d'un objet non ajoutable en objet ajoutable. Toutefois, utilisez la méthode suivante pour effectuer cette conversion :
Utilisez l'opération API AppendObject pour créer un nouvel objet ajoutable vide.
Téléchargez l'objet original et lisez son contenu.
Utilisez l'opération API AppendObject pour ajouter le contenu à l'objet nouvellement créé.
Le processus de conversion implique la relecture et le retéléchargement du contenu. Une fois la conversion terminée, vérifiez la disponibilité de l'objet.