すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:追加アップロード (Go SDK V2)

最終更新日:Nov 09, 2025

追加アップロードを使用すると、既存の追加可能オブジェクトの末尾にコンテンツを直接追加できます。このトピックでは、OSS SDK for Go を使用して追加アップロードを実行する方法について説明します。

使用上の注意

  • このトピックのサンプルコードでは、中国 (杭州) リージョンのリージョン ID として cn-hangzhou を使用します。デフォルトでは、パブリックエンドポイントを使用してバケット内のリソースにアクセスします。バケットが配置されているのと同じリージョン内の他の Alibaba Cloud サービスを使用してバケット内のリソースにアクセスする場合は、内部エンドポイントを使用できます。OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。

  • このトピックでは、アクセス資格情報は環境変数から読み取られます。アクセス資格情報の設定方法の詳細については、「アクセス資格情報の設定」をご参照ください。

  • コンテンツを追加するファイルが存在しない場合、追加アップロード API 操作を呼び出すと、追加可能オブジェクトが作成されます。

  • コンテンツを追加するファイルが存在する場合:

    • ファイルが追加可能オブジェクトであり、指定された追加位置がファイルの現在の長さと同じである場合、コンテンツはファイルの末尾に追加されます。

    • ファイルが追加可能オブジェクトであるが、指定された追加位置がファイルの現在の長さと同じでない場合、PositionNotEqualToLength 例外がスローされます。

    • ファイルが単純なアップロードを使用してアップロードされた通常のオブジェクトなど、追加可能オブジェクトでない場合、ObjectNotAppendable 例外がスローされます。

権限

デフォルトでは、Alibaba Cloud アカウントは完全な権限を持っています。Alibaba Cloud アカウント下の RAM ユーザーまたは RAM ロールは、デフォルトではいかなる権限も持っていません。Alibaba Cloud アカウントまたはアカウント管理者は、RAM ポリシーまたはバケットポリシーを通じて操作権限を付与する必要があります。

API

アクション

定義

AppendObject

oss:PutObject

この操作を呼び出して、既存のオブジェクトにオブジェクトを追加することでオブジェクトをアップロードできます。

oss:PutObjectTagging

既存のオブジェクトにオブジェクトを追加してオブジェクトをアップロードする際に、x-oss-tagging を通じてオブジェクトタグを指定する場合、この権限が必要です。

メソッド定義

追加アップロードのシナリオでは、OSS SDK for Go は、バケット内のオブジェクトのファイル読み取りおよび書き込み動作をシミュレートするための新しい AppendFile 操作を提供します。次の表に、AppendFile および AppendObject 操作について説明します。

操作名

説明

Client.AppendObject

追加アップロードを実行します。最終的なオブジェクトのサイズは最大 5 GiB です。

CRC-64 データ整合性チェックをサポートします (デフォルトで有効)。

プログレスバーをサポートします。

リクエストボディは io.Reader 型です。io.Seeker 型がサポートされている場合、失敗時に再送が可能です。この操作はべき等ではなく、再送が失敗する可能性があります。

Client.AppendFile

Client.AppendObject 操作と同じ機能を提供します。

再送失敗に対するフォールトトレランスを最適化します。

AppendOnlyFile 操作を含みます。

AppendOnlyFile.Write

AppendOnlyFile.WriteFrom

プレミアム追加アップロード API: AppendFile

AppendFile 操作を呼び出して、データを追加してアップロードできます。オブジェクトが存在しない場合、追加可能オブジェクトが作成されます。オブジェクトは存在するが追加可能オブジェクトではない場合、エラーが返されます。

次のサンプルコードは、AppendFile 操作を定義する方法の例を示しています。

type AppendOnlyFile struct {
...
}

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

リクエストパラメーター

パラメーター

タイプ

説明

ctx

context.Context

リクエストのコンテキスト。

bucket

string

バケットの名前。

key

string

オブジェクトの名前。

optFns

...func(*AppendOptions)

オプション。ファイルを追加するための構成オプション。

次の表に、AppendOptions のパラメーターを説明します。

パラメーター

タイプ

説明

RequestPayer

*string

リクエスト元支払いモードが有効になっている場合は、このパラメーターを 'requester' に設定します。

CreateParameter

*AppendObjectRequest

最初のアップロード時にオブジェクトのメタデータを設定するために使用されます。メタデータには、ContentType、Metadata、権限、およびストレージタイプが含まれます。詳細については、「AppendObjectRequest」をご参照ください。

戻り値

戻り値

タイプ

説明

file

*AppendOnlyFile

追加可能ファイルのインスタンス。このパラメーターは、err が nil の場合にのみ有効です。詳細については、「AppendOnlyFile」をご参照ください。

err

error

追加可能ファイルを開くステータス。操作が失敗した場合、err は nil ではありません。

次の表に、AppendOnlyFile 操作について説明します。

操作名

説明

Close() error

ファイルハンドルを閉じてリソースを解放します。

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

b のデータをデータストリームに書き込み、書き込まれたバイト数と発生したエラーを返します。

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

r のデータをデータストリームに書き込み、書き込まれたバイト数と発生したエラーを返します。

Stat() (os.FileInfo, error)

オブジェクトサイズ、最終変更時刻、メタデータなどのオブジェクト情報を取得します。

基本追加アップロード API: AppendObject

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

リクエストパラメーター

パラメーター

タイプ

説明

ctx

context.Context

リクエストのコンテキスト。リクエストの合計タイムアウト期間を設定するために使用できます。

request

*AppendObjectRequest

特定の API 操作のリクエストパラメーター。詳細については、「AppendObjectRequest」をご参照ください。

optFns

...func(*Options)

オプション。操作レベルの構成パラメーター。詳細については、「Options」をご参照ください。

戻り値

戻り値

タイプ

説明

result

*AppendObjectResult

API 操作の戻り値。このパラメーターは、err が nil の場合にのみ有効です。詳細については、「AppendObjectResult」をご参照ください。

err

error

リクエストのステータス。リクエストが失敗した場合、err は nil ではありません。

サンプルコード

AppendFile を使用した追加アップロードの実行

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"
)

// グローバル変数を定義します。
var (
	region     string // ストレージリージョン。
	bucketName string // バケット名。
	objectName string // オブジェクト名。
)

// init 関数は、コマンドラインパラメーターを初期化するために使用されます。
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() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// バケット名が空かどうかを確認します。
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// ストレージリージョンが空かどうかを確認します。
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// オブジェクト名が空かどうかを確認します。
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// OSS クライアントを構成します。
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// OSS クライアントを作成します。
	client := oss.NewClient(cfg)

	// 追加可能ファイルのインスタンスを作成します。
	f, err := client.AppendFile(context.TODO(),
		bucketName,
		objectName,
		func(ao *oss.AppendOptions) {
			ao.CreateParameter = &oss.AppendObjectRequest{
				Acl: oss.ObjectACLPrivate, // オブジェクトのアクセス権限を非公開に設定します。
				Metadata: map[string]string{
					"user": "jack", // オブジェクトのメタデータを設定します。
				},
				Tagging: oss.Ptr("key=value"), // オブジェクトのタグを設定します。
			}
		})

	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	defer f.Close() // 関数が終了するときにデータストリームが閉じられることを確認します。

	// ローカルファイル example1.txt を開きます。
	lf, err := os.Open("/local/dir/example1.txt")
	if err != nil {
		log.Fatalf("failed to open local file %v", err)
	}

	// example1.txt のコンテンツを OSS オブジェクトに追加します。
	_, err = f.WriteFrom(lf)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	lf.Close() // ローカルファイルを閉じます。

	// ローカルファイル example2.txt を開きます。
	lf, err = os.Open("/local/dir/example2.txt")
	if err != nil {
		log.Fatalf("failed to open local file %v", err)
	}

	// example2.txt のコンテンツを OSS オブジェクトに追加します。
	_, err = f.WriteFrom(lf)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}
	lf.Close() // ローカルファイルを閉じます。

	// ローカルファイル example3.txt のコンテンツを読み取ります。
	lb, err := os.ReadFile("/local/dir/example3.txt")
	if err != nil {
		log.Fatalf("failed to read local file %v", err)
	}

	// example3.txt のコンテンツを OSS オブジェクトに追加します。
	_, err = f.Write(lb)
	if err != nil {
		log.Fatalf("failed to append file %v", err)
	}

	// 追加アップロードが成功したログ情報を出力します。
	log.Printf("append file successfully")
}

AppendObject を使用した追加アップロードの実行

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"
)

// グローバル変数を定義します。
var (
	region     string
	bucketName string
	objectName string
)

// init 関数は、コマンドラインパラメーターを初期化するために使用されます。
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() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// 追加アップロードの初期位置を定義します。
	var (
		position = int64(0)
	)

	// バケット名が空かどうかを確認します。
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// リージョンが空かどうかを確認します。
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// オブジェクト名が空かどうかを確認します。
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// デフォルトの構成をロードし、資格情報プロバイダーとリージョンを設定します。
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// OSS クライアントを作成します。
	client := oss.NewClient(cfg)

	// 追加するコンテンツを定義します。
	content := "hi append object"

	// AppendObject リクエストを作成します。
	request := &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(position),
		Body:     strings.NewReader(content),
	}

	// AppendObject リクエストを実行し、結果を処理します。
	// 最初の追加アップロードの位置は 0 です。戻り値には、次の追加アップロードの位置が含まれます。
	result, err := client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// 2 番目の AppendObject リクエストを作成します。
	request = &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(result.NextPosition), // 最初の AppendObject リクエストの戻り値から NextPosition を取得します。
		Body:     strings.NewReader("hi append object"),
	}

	// 2 番目の AppendObject リクエストを実行し、結果を処理します。
	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)
}

一般的なシナリオ

追加アップロードを実行してプログレスバーを表示する

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"
)

// グローバル変数を定義します。
var (
	region     string
	bucketName string
	objectName string
)

// init 関数は、コマンドラインパラメーターを初期化するために使用されます。
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() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// 追加アップロードの初期位置を定義します。
	var (
		position = int64(0)
	)

	// バケット名が空かどうかを確認します。
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// リージョンが空かどうかを確認します。
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// オブジェクト名が空かどうかを確認します。
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// デフォルトの構成をロードし、資格情報プロバイダーとリージョンを設定します。
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// OSS クライアントを作成します。
	client := oss.NewClient(cfg)

	// 追加するコンテンツを定義します。
	content := "hi append object"

	// AppendObject リクエストを作成します。
	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)
		}, // プログレスコールバック関数。アップロードの進捗状況を表示するために使用されます。
	}

	// 最初の AppendObject リクエストを実行し、結果を処理します。
	// 最初の追加アップロードの位置は 0 です。戻り値には、次の追加アップロードの位置が含まれます。
	result, err := client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// 2 番目の AppendObject リクエストを作成します。
	request = &oss.AppendObjectRequest{
		Bucket:   oss.Ptr(bucketName),
		Key:      oss.Ptr(objectName),
		Position: oss.Ptr(result.NextPosition), // 最初の AppendObject リクエストの戻り値から NextPosition を取得します。
		Body:     strings.NewReader("hi append object"),
		ProgressFn: func(increment, transferred, total int64) {
			fmt.Printf("increment:%v, transferred:%v, total:%v\n", increment, transferred, total)
		}, // プログレスコールバック関数。アップロードの進捗状況を表示するために使用されます。
	}

	// 2 番目の AppendObject リクエストを実行し、結果を処理します。
	result, err = client.AppendObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to append object %v", err)
	}

	// 追加されたオブジェクトの versionId を出力します。
	log.Printf("append object result:%#v\n", *result.VersionId)
}

リファレンス

  • 追加アップロードの完全なサンプルコードについては、「GitHub の例」および「開発者ガイド」をご参照ください。

  • 追加アップロードのプレミアム API 操作の詳細については、「AppendFile」をご参照ください。

  • 追加アップロードの基本 API 操作の詳細については、「AppendObject」をご参照ください。