このトピックでは、object Storage Service (OSS) のバージョン管理が有効なバケットにオブジェクトをコピーする方法について説明します。 CopyObjectを呼び出して最大1 GBのサイズのオブジェクトをコピーし、UploadPartCopyを呼び出して1 GBを超えるサイズのオブジェクトをマルチパートコピーを使用してコピーできます。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。 OSSと同じリージョンにある他のAlibaba CloudサービスからOSSにアクセスする場合は、内部エンドポイントを使用します。 OSSリージョンとエンドポイントの詳細については、「リージョン、エンドポイント、オープンポート」をご参照ください。
このトピックでは、アクセス資格情報は環境変数から取得します。 アクセス資格情報の設定方法の詳細については、「アクセス資格情報の設定」をご参照ください。
このトピックでは、OSSエンドポイントを使用してOSSClientインスタンスを作成します。 カスタムドメイン名またはSTS (Security Token Service) を使用してOSSClientインスタンスを作成する場合は、「初期化」をご参照ください。
オブジェクトをコピーするには、
oss:GetObject
およびoss:PutObject
権限が必要です。 詳細については、「RAMユーザーへのカスタムポリシーのアタッチ」をご参照ください。
サンプルコード
小さなオブジェクトをコピーする
CopyObjectを呼び出して、最大1 GBのサイズのオブジェクトをソースバケットから同じリージョン内の宛先バケットにコピーできます。
CopyObjectリクエストのx-oss-copy-sourceヘッダーにバージョンIDを指定しない場合、オブジェクトの現在のバージョンがコピーされます。 オブジェクトの現在のバージョンが削除マーカーである場合、OSSはHTTPステータスコード404を返します。 HTTPステータスコードは、オブジェクトが存在しないことを示します。 x-oss-copy-sourceヘッダーにバージョンIDを指定して、特定のオブジェクトバージョンをコピーできます。 削除マーカーはコピーできません。
以前のバージョンのオブジェクトを同じバケットにコピーできます。 コピーされた以前のバージョンがオブジェクトの現在のバージョンになります。 このようにして、オブジェクトの以前のバージョンが復元されます。
宛先バケットのバージョン管理が有効になっている場合、OSSは宛先オブジェクトの一意のバージョンIDを生成します。 バージョンIDは、レスポンスのx-oss-version-idヘッダーの値として返されます。 宛先バケットのバージョン管理が無効または一時停止されている場合、OSSは、宛先オブジェクトのバージョンIDがnullのバージョンを生成し、バージョンIDがnullの以前のバージョンを上書きします。
バージョン管理が有効または一時停止されている宛先バケットには、追加可能オブジェクトをコピーできません。
次のサンプルコードは、小さなオブジェクトをコピーする方法の例を示しています。
package main
import (
"log"
"net/http"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 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.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// Create an OSSClient instance.
// 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. Specify your actual endpoint.
// 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. Specify the actual region.
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// Specify the version of the signature algorithm.
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)
}
// Specify the name of the bucket.
bucketName := "yourBucketName"
// Specify the full path of the source object. Do not include the bucket name in the full path.
objectName := "yourObjectName"
// Specify the full path of the destination object. Do not include the bucket name in the full path.
destObjectName := "yourDestObjectName"
// Create a bucket.
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
// Copy the specified version of the object to the same bucket and query the version ID of the destination object.
var retHeader http.Header
_, err = bucket.CopyObject(objectName, destObjectName, oss.VersionId("yourObjectVersionId"), oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to copy object '%s' to '%s': %v", objectName, destObjectName, err)
}
// Display the version information.
versionId := oss.GetVersionId(retHeader)
copySourceVersionId := oss.GetCopySrcVersionId(retHeader)
log.Printf("x-oss-version-id: %s", versionId)
log.Printf("x-oss-copy-source-version-id: %s", copySourceVersionId)
}
大きなオブジェクトをコピーする
サイズが1 GBを超えるオブジェクトをコピーする場合は、UploadPartCopyを呼び出してマルチパートコピーを実行します。
デフォルトでは、UploadPartCopy操作は、指定されたオブジェクトの現在のバージョンからデータをコピーして部品をアップロードします。 x-oss-copy-sourceリクエストヘッダーにバージョンIDを指定して、既存のオブジェクトの指定されたバージョンからデータをコピーして部品をアップロードする条件を指定できます。 例: x-oss-copy-source: /SourceBucketName/SourceObjectName?versionId=111111
SourceObjectNameパラメーターの値は、URLエンコードされている必要があります。 コピーされたオブジェクトのバージョンIDは、レスポンスのx-oss-copy-source-version-idヘッダーの値として返されます。
リクエストにバージョンIDが指定されておらず、ソースオブジェクトの現在のバージョンが削除マーカーである場合、OSSは404 Not Foundを返します。 リクエストにバージョンIDが指定されており、ソースオブジェクトの指定されたバージョンが削除マーカーである場合、OSSは400 Bad requestを返します。
次のサンプルコードは、ラージオブジェクトをパーツごとにコピーする方法の例を示しています。
package main
import (
"log"
"net/http"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 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.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// Create an OSSClient instance.
// 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. Specify your actual endpoint.
// 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. Specify the actual region.
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// Specify the version of the signature algorithm.
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)
}
// Specify the name of the bucket.
bucketName := "yourBucketName"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
// Specify the full path of the object. Do not include the bucket name in the full path.
objectName := "yourObjectName"
fileName := "yourFileName"
futureDate := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
var retHeader http.Header
// Split the file.
chunks, err := oss.SplitFileByPartNum(fileName, 3)
if err != nil {
log.Fatalf("Failed to split file '%s': %v", fileName, err)
}
// Upload a large object as the source object.
err = bucket.PutObjectFromFile(objectName, fileName, oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to put object '%s' from file '%s': %v", objectName, fileName, err)
}
// Query the version ID of the source object.
versionId := oss.GetVersionId(retHeader)
log.Printf("Source object version ID: %s", versionId)
// Configure the parameters for the object copy task.
options := []oss.Option{
oss.Expires(futureDate),
oss.Meta("my", "myprop"),
}
// Specify the name of the destination object.
objectDest := objectName + "dest"
var parts []oss.UploadPart
copyOptions := []oss.Option{
oss.VersionId(versionId),
oss.GetResponseHeader(&retHeader),
}
// Initiate a multipart upload task.
imu, err := bucket.InitiateMultipartUpload(objectDest, options...)
if err != nil {
log.Fatalf("Failed to initiate multipart upload for object '%s': %v", objectDest, err)
}
// Copy the large object.
for _, chunk := range chunks {
part, err := bucket.UploadPartCopy(imu, bucketName, objectName, chunk.Offset, chunk.Size, int(chunk.Number), copyOptions...)
if err != nil {
log.Fatalf("Failed to upload part %d of object '%s': %v", chunk.Number, objectName, err)
}
parts = append(parts, part)
// Display the value of the x-oss-copy-source-version-id header.
log.Printf("x-oss-copy-source-version-id: %s", oss.GetCopySrcVersionId(retHeader))
}
// Complete the multipart upload task.
_, err = bucket.CompleteMultipartUpload(imu, parts, oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to complete multipart upload for object '%s': %v", objectDest, err)
}
// Display the value of the x-oss-version-id header.
log.Printf("x-oss-version-id: %s", oss.GetVersionId(retHeader))
}
関連ドキュメント
小さなオブジェクトをコピーするために呼び出すことができるAPI操作の詳細については、「CopyObject」をご参照ください。
ラージオブジェクトをコピーするために呼び出すことができるAPI操作の詳細については、「UploadPartCopy」をご参照ください。