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

Object Storage Service:マルチパートコピーを使用したオブジェクトのコピー (Go SDK V2)

最終更新日:Nov 09, 2025

このトピックでは、Object Storage Service (OSS) SDK for Go 2.0 の UploadPartCopy 操作を呼び出して、マルチパートコピーを使用して、同じリージョン内のソースバケットから宛先バケットにオブジェクトをコピーする方法について説明します。宛先バケットは、ソースバケットと同じでも、別のバケットでもかまいません。

使用上の注意

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

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

  • オブジェクトをコピーするには、ソースオブジェクトに対する読み取り権限と、宛先バケットに対する読み取りおよび書き込み権限が必要です。

  • ソースバケットと宛先バケットは、同じリージョンに配置する必要があります。たとえば、中国 (杭州) リージョンにあるバケット内のオブジェクトを、中国 (青島) リージョンにある別のバケットにコピーすることはできません。

  • ソースバケットと宛先バケットにリテンションポリシーが設定されていないことを確認してください。設定されている場合、The object you specified is immutable. というエラーメッセージが返されます。

メソッド

func (c *Client) UploadPartCopy(ctx context.Context, request *UploadPartCopyRequest, optFns ...func(*Options)) (*UploadPartCopyResult, error)

リクエストパラメーター

パラメーター

タイプ

説明

ctx

context.Context

リクエストのコンテキスト。リクエストの合計期間を指定するために使用できます。

request

*UploadPartCopyRequest

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

optFns

...func(*Options)

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

応答パラメーター

パラメーター

タイプ

説明

result

*UploadPartCopyResult

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

err

error

リクエストのステータス。リクエストが失敗した場合、err の値は nil 以外になります。

マルチパートコピーのプロセス

シャーディングされたコピーには、次の 3 つのステップが含まれます:

  1. マルチパートアップロードタスクを開始します。

    Client.InitiateMultipartUpload メソッドを使用して、OSS で一意のアップロード ID を取得します。

  2. パートをアップロードします。

    Client.UploadPartCopy メソッドを使用してパートをアップロードします。

    説明
    • 特定のアップロード ID を持つマルチパートアップロードタスクを実行してアップロードされたパートの場合、パート番号はオブジェクト内の相対的な位置を識別します。パートをアップロードし、そのパート番号を再利用して別のパートをアップロードすると、新しいパートが元のパートを上書きします。

    • OSS は、アップロードされた各パートの MD5 ハッシュを応答の ETag ヘッダーに含めます。

    • OSS は、アップロードされたパートの MD5 ハッシュを計算し、その MD5 ハッシュを OSS SDK for Go によって計算された MD5 ハッシュと比較します。2 つのハッシュが異なる場合、OSS は InvalidDigest エラーコードを返します。

  3. マルチパートアップロードタスクを完了します。

    すべてのパートがアップロードされた後、Client.CompleteMultipartUpload メソッドを使用してこれらのパートを完全なオブジェクトに結合します。

次のサンプルコードは、マルチパートコピーを使用してソースバケットから宛先バケットにオブジェクトをコピーし、パートを結合して完全なオブジェクトにする方法の例を示しています:

package main

import (
	"context"
	"flag"
	"log"
	"sync"

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

// グローバル変数を指定します。
var (
	region         string // リージョン。
	srcBucketName string // ソースバケットの名前。
	srcObjectName string // ソースオブジェクトの名前。
	destBucketName string // 宛先バケットの名前。
	destObjectName string // 宛先オブジェクトの名前。
)

// コマンドラインパラメーターを初期化するために使用される init 関数を指定します。
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&srcBucketName, "src-bucket", "", "The name of the source bucket.")
	flag.StringVar(&srcObjectName, "src-object", "", "The name of the source object.")
	flag.StringVar(&destBucketName, "dest-bucket", "", "The name of the destination bucket.")
	flag.StringVar(&destObjectName, "dest-object", "", "The name of the destination object.")
}

func main() {
	// コマンドラインパラメーターを解析します。
	flag.Parse()

	// アップロード ID を指定します。
	var uploadId string

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

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

	// 宛先バケット名が指定されていない場合は、ソースバケット名が使用されます。
	if len(destBucketName) == 0 {
		destBucketName = srcBucketName
	}

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

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

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

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

	// マルチパートアップロードリクエストを初期化します。
	initRequest := &oss.InitiateMultipartUploadRequest{
		Bucket: oss.Ptr(destBucketName),
		Key:    oss.Ptr(destObjectName),
	}
	initResult, err := client.InitiateMultipartUpload(context.TODO(), initRequest)
	if err != nil {
		log.Fatalf("failed to initiate multipart upload %v", err)
	}

	// マルチパートコピーの結果を表示します。
	log.Printf("initiate multipart upload result:%#v\n", *initResult.UploadId)
	uploadId = *initResult.UploadId

	// wait group と相互排他 (mutex) を初期化します。
	var wg sync.WaitGroup
	var parts []oss.UploadPart
	count := 3
	var mu sync.Mutex

	// マルチパートアップロードのために複数のゴルーチンを開始します。
	for i := 0; i < count; i++ {
		wg.Add(1)
		go func(partNumber int, i int) {
			defer wg.Done()

			// マルチパートアップロードリクエストを作成します。
			partRequest := &oss.UploadPartCopyRequest{
				Bucket:       oss.Ptr(destBucketName), // 宛先バケットの名前。
				Key:          oss.Ptr(destObjectName), // 宛先オブジェクトの名前。
				SourceBucket: oss.Ptr(srcBucketName), // ソースバケットの名前。
				SourceKey:     oss.Ptr(srcObjectName), // ソースオブジェクトの名前。
				PartNumber: int32(partNumber), // パート番号。
				const uploadId = '<Upload Id>'; // マルチパートアップロードタスクのアップロード ID。
			}

			// マルチパートアップロードリクエストを送信します。
			partResult, err := client.UploadPartCopy(context.TODO(), partRequest)
			if err != nil {
				log.Fatalf("failed to upload part copy %d: %v", partNumber, err)
			}

			// マルチパートアップロードの結果を記録します。
			part := oss.UploadPart{
				PartNumber: partRequest.PartNumber,
				ETag:       partResult.ETag,
			}

			// mutex を使用して共有データを保護します。
			mu.Lock()
			parts = append(parts, part)
			mu.Unlock()
		}(i+1, i)
	}

	// すべてのゴルーチンが完了するまで待ちます。
	wg.Wait()

	// マルチパートアップロードリクエストを完了します。
	request := &oss.CompleteMultipartUploadRequest{
		Bucket:   oss.Ptr(destBucketName),
		Key:      oss.Ptr(destObjectName),
		UploadId: oss.Ptr(uploadId),
		CompleteMultipartUpload: &oss.CompleteMultipartUpload{
			Parts: parts,
		},
	}
	result, err := client.CompleteMultipartUpload(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to complete multipart upload %v", err)
	}

	// 結果を表示します。
	log.Printf("complete multipart upload result:%#v\n", result)
}

関連ドキュメント

  • マルチパートコピーを使用してオブジェクトをコピーするために使用される完全なサンプルコードについては、GitHub をご参照ください。

  • マルチパートアップロードタスクを開始するために呼び出すことができる API 操作の詳細については、「InitiateMultipartUpload」をご参照ください。

  • マルチパートコピーを使用してオブジェクトをコピーするために呼び出すことができる API 操作の詳細については、「UploadPartCopy」をご参照ください。

  • マルチパートアップロードタスクを完了するために呼び出すことができる API 操作の詳細については、「CompleteMultipartUpload」をご参照ください。