このトピックでは、同じリージョン内のバケット内またはバケット間でオブジェクトをコピーする方法について説明します。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントが使用されています。 OSS と同じリージョン内の他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用します。 OSS のリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス認証情報は環境変数から取得されます。 アクセス認証情報を設定する方法の詳細については、「アクセス認証情報を設定する」をご参照ください。
このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスが作成されます。 カスタムドメイン名または Security Token Service (STS) を使用して OSSClient インスタンスを作成する場合は、「OSSClient インスタンスの設定」をご参照ください。
オブジェクトをコピーするには、ソースオブジェクトに対する読み取り権限と、デスティネーションバケットに対する読み取りおよび書き込み権限が必要です。
ソースバケットとデスティネーションバケットに保存ポリシーが設定されていないことを確認してください。 そうしないと、指定したオブジェクトは変更不可です。 というエラーメッセージが返されます。
ソースバケットとデスティネーションバケットは同じリージョンにある必要があります。 たとえば、中国 (杭州) リージョンにあるバケットから中国 (青島) リージョンにある別のバケットにオブジェクトをコピーすることはできません。
サンプルコード
小さなオブジェクトをコピーする
CopyObject を呼び出して、同じリージョン内のバケット内またはバケット間でオブジェクトをコピーできます。 サイズが 1 GB 未満のオブジェクトをコピーするには、CopyObject を呼び出すことをお勧めします。
同じバケット内のオブジェクトをコピーする
package main
import (
"log"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// OSSClient インスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 実際のエンドポイントを指定してください。
// バケットが配置されているリージョンを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。 実際のリージョンを指定してください。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 署名アルゴリズムのバージョンを指定します。
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// バケットの名前を指定します。 例: examplebucket。
bucketName := "examplebucket"
// ソースオブジェクトの完全なパスを指定します。 例: srcdir/srcobject.jpg。
objectName := "srcdir/srcobject.jpg"
// デスティネーションオブジェクトの完全なパスを指定します。 例: destdir/destobject.jpg。
destObjectName := "destdir/destobject.jpg"
// バケット情報を取得します。
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
// デスティネーションオブジェクトのメタデータを指定します。
expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
tag1 := oss.Tag{
Key: "a",
Value: "1",
}
taggingInfo := oss.Tagging{
Tags: []oss.Tag{tag1},
}
options := []oss.Option{
oss.MetadataDirective(oss.MetaReplace),
oss.Expires(expires),
oss.SetTagging(taggingInfo),
// ソースオブジェクトのタグをデスティネーションオブジェクトにコピーします。
// oss.TaggingDirective(oss.TaggingCopy),
// OSS がデスティネーションオブジェクトを作成するときに、デスティネーションオブジェクトのアクセス制御リスト (ACL) を非公開に設定します。
// oss.ObjectACL(oss.ACLPrivate),
// Key Management Service (KMS) によって管理されるカスタマーマスターキー (CMK) を指定します。 このパラメーターは、x-oss-server-side-encryption が KMS に設定されている場合にのみ有効になります。
// oss.ServerSideEncryptionKeyID("9468da86-3509-4f8d-a61e-6eab1eac****"),
// OSS がオブジェクトを作成するときに、デスティネーションオブジェクトの暗号化に使用するサーバー側暗号化アルゴリズムを指定します。
// oss.ServerSideEncryption("AES256"),
// ソースオブジェクトのメタデータをデスティネーションオブジェクトにコピーします。
// oss.MetadataDirective(oss.MetaCopy),
// CopyObject 操作で、ソースバケットと同じ名前のオブジェクトを上書きするかどうかを指定します。 この例では、このパラメーターは true に設定されています。 値 true は、操作がソースバケットと同じ名前のオブジェクトを上書きしないことを示します。
// oss.ForbidOverWrite(true),
// リクエストで指定した ETag 値がソースオブジェクトの ETag 値と同じである場合、OSS はオブジェクトをコピーし、200 OK を返します。
// oss.CopySourceIfMatch("5B3C1A2E053D763E1B002CC607C5****"),
// リクエストで指定した ETag 値がソースオブジェクトの ETag 値と異なる場合、OSS はオブジェクトをコピーし、200 OK を返します。
// oss.CopySourceIfNoneMatch("5B3C1A2E053D763E1B002CC607C5****"),
// リクエストで指定された時間がオブジェクトが変更された実際の時間よりも早い場合、OSS はオブジェクトをコピーし、200 OK を返します。
// oss.CopySourceIfModifiedSince(time.Date(2021, time.December, 9, 7, 1, 56, 0, time.UTC)),
// リクエストで指定された時間がオブジェクトの変更時刻と同じかそれ以降の場合、OSS はオブジェクトをコピーし、200 OK を返します。
// oss.CopySourceIfUnmodifiedSince(time.Date(2021, time.December, 9, 7, 1, 56, 0, time.UTC)),
// デスティネーションオブジェクトのストレージクラスを指定します。 この例では、ストレージクラスは標準に設定されています。
// oss.StorageClass("Standard"),
}
// リクエストで指定したメタデータを使用して、ソースオブジェクトのメタデータを上書きします。
_, err = bucket.CopyObject(objectName, destObjectName, options...)
if err != nil {
log.Fatalf("Failed to copy object from '%s' to '%s': %v", objectName, destObjectName, err)
}
log.Printf("Successfully copied object from '%s' to '%s'", objectName, destObjectName)
}
同じリージョン内のバケット間でオブジェクトをコピーする
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// OSSClient インスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 実際のエンドポイントを指定してください。
// バケットが配置されているリージョンを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。 実際のリージョンを指定してください。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 署名アルゴリズムのバージョンを指定します。
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// ソースバケットの名前を指定します。 例: srcbucket。
srcBucketName := "srcbucket"
// ソースオブジェクトの完全なパスを指定します。 例: srcobject.jpg。
srcObjectName := "srcobject.jpg"
// デスティネーションオブジェクトの完全なパスを指定します。 例: destobject.jpg。
dstObjectName := "destobject.jpg"
// デスティネーションバケットの名前を指定します。 例: destbucket。
destBucketName := "destbucket"
// デスティネーションバケットを作成します。
bucket, err := client.Bucket(destBucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", destBucketName, err)
}
// srcbucket から srcobject.jpg オブジェクトを destbucket の destobject.jpg オブジェクトにコピーします。
_, err = bucket.CopyObjectFrom(srcBucketName, srcObjectName, dstObjectName)
if err != nil {
log.Fatalf("Failed to copy object from '%s/%s' to '%s/%s': %v", srcBucketName, srcObjectName, destBucketName, dstObjectName, err)
}
log.Printf("Successfully copied object from '%s/%s' to '%s/%s'", srcBucketName, srcObjectName, destBucketName, dstObjectName)
}
大きなオブジェクトをコピーする
次のコードは、大きなオブジェクトをコピーする方法の例を示しています。
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// OSSClient インスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 実際のエンドポイントを指定してください。
// バケットが配置されているリージョンを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合は、リージョンを cn-hangzhou に設定します。 実際のリージョンを指定してください。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 署名アルゴリズムのバージョンを指定します。
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// バケットの名前を指定します。 例: examplebucket。
bucketName := "examplebucket"
// バケット情報を取得します。
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
// ソースオブジェクトの完全なパスを指定します。 例: srcobject.txt。
objectSrc := "srcobject.txt"
// デスティネーションオブジェクトの完全なパスを指定します。 例: destobject.txt。
objectDest := "destobject.txt"
// ローカルファイルの完全なパスを指定します。
fileName := "D:\\localpath\\examplefile.txt"
// オブジェクトを複数のチャンクに分割します。
chunks, err := oss.SplitFileByPartNum(fileName, 3)
if err != nil {
log.Fatalf("Failed to split file: %v", err)
}
// ファイルを OSS にアップロードします。
err = bucket.PutObjectFromFile(objectSrc, fileName)
if err != nil {
log.Fatalf("Failed to upload object '%s' from file '%s': %v", objectSrc, fileName, err)
}
// マルチパートアップロードを開始します。
imur, err := bucket.InitiateMultipartUpload(objectDest)
if err != nil {
log.Fatalf("Failed to initiate multipart upload for '%s': %v", objectDest, err)
}
var parts []oss.UploadPart
for _, chunk := range chunks {
// マルチパートアップロードのオプションを指定します。
options := []oss.Option{}
// アップロードされたパーツをコピーします。
part, err := bucket.UploadPartCopy(imur, bucketName, objectSrc, chunk.Offset, chunk.Size, chunk.Number, options...)
if err != nil {
log.Fatalf("Failed to upload part %d of '%s': %v", chunk.Number, objectSrc, err)
}
parts = append(parts, part)
}
// マルチパートアップロードを完了します。
cmur, err := bucket.CompleteMultipartUpload(imur, parts)
if err != nil {
log.Fatalf("Failed to complete multipart upload for '%s': %v", objectDest, err)
}
log.Printf("Multipart upload completed successfully for '%s'. cmur: %v", objectDest, cmur)
}
関連情報
オブジェクトのコピーに使用される完全なサンプルコードについては、GitHub をご覧ください。
小さなオブジェクトをコピーするために呼び出すことができる API 操作の詳細については、「CopyObject」をご参照ください。
大きなオブジェクトをコピーするために呼び出すことができる API 操作の詳細については、「UploadPartCopy」をご参照ください。