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

Object Storage Service:オブジェクトのコピー

最終更新日:Oct 28, 2024

このトピックでは、バケット内または同じリージョン内のバケット間でオブジェクトをコピーする方法について説明します。

使用上の注意

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

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

  • このトピックでは、OSSエンドポイントを使用してOSSClientインスタンスを作成します。 カスタムドメイン名またはSTS (Security Token Service) を使用してOSSClientインスタンスを作成する場合は、「初期化」をご参照ください。

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

  • ソースバケットとターゲットバケットに保持ポリシーが設定されていないことを確認します。 それ以外の場合、エラーメッセージ指定したオブジェクトは不変です。 が返されます。

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

小さなオブジェクトをコピーする

簡易コピーを使用して、サイズが1 GB未満のオブジェクトをコピーできます。 次のコードでは、単純コピーを使用して、srcexampleobject.txtという名前のオブジェクトをsrcexamplebucketからdestexamplebucket内のdestexampleobject.txtという名前のオブジェクトにコピーする方法の例を示します。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 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. 
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Specify the name of the source bucket. Example: srcexamplebucket. 
src_bucket_name = 'srcexamplebucket'
# Specify the name of the destination bucket. The destination bucket must be in the same region as the source bucket. Example: destexamplebucket. 
# If you copy an object within a bucket, make sure that you specify the same bucket name for the source bucket and destination bucket. 
dest_bucket_name = 'destexamplebucket'

# 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. 
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"
bucket = oss2.Bucket(auth, endpoint, dest_bucket_name, region=region)


# Specify the full path of the source object. Do not include the bucket name in the full path. Example: srcexampleobject.txt. 
src_object_name = 'srcexampleobject.txt'
# Specify the full path of the destination object. Do not include the bucket name in the full path. Example: destexampleobject.txt. 
dest_object_name = 'destexampleobject.txt'

# headers = dict()
# Specify whether the CopyObject operation overwrites an object that has the same name. In this example, this parameter is set to true, which specifies that the operation does not overwrite an object that has the same name. 
# headers['x-oss-forbid-overwrite'] = 'true'
# Specify the path of the source object. 
# headers[OSS_COPY_OBJECT_SOURCE] = '/example-bucket-by-util/recode-test.txt'
# If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
# headers['x-oss-copy-source-if-match'] = '5B3C1A2E053D763E1B002CC607C5****'
# If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
# headers['x-oss-copy-source-if-none-match'] = '5B3C1A2E053D763E1B002CC607C5****'
# If the time that is specified in the request is equal to or later than the actual modified time of the object, OSS copies the object and returns 200 OK. 
# headers['x-oss-copy-source-if-unmodified-since'] = '2021-12-09T07:01:56.000Z'
# If the source object is modified after the time that is specified in the request, OSS copies the object. 
# headers['x-oss-copy-source-if-modified-since'] = '2021-12-09T07:01:56.000Z'
# Specify the method that is used to configure the metadata of the destination object. If you set the method to COPY, the metadata of the source object is copied to the destination object. 
# headers[OSS_METADATA_DIRECTIVE] = 'COPY'
# Specify the server-side encryption algorithm that is used to encrypt the destination object when OSS creates the destination object. 
# headers[OSS_SERVER_SIDE_ENCRYPTION] = 'KMS'
# Specify the customer master key (CMK) that is managed by Key Management Service (KMS). This parameter takes effect only when x-oss-server-side-encryption is set to KMS. 
# headers['x-oss-server-side-encryption-key-id'] = '9468da86-3509-4f8d-a61e-6eab1eac****'
# Specify the access control list (ACL) of the destination object. In this example, this parameter is set to OBJECT_ACL_PRIVATE, which indicates that only the object owner and authorized users have read and write permissions on the object. 
# headers[OSS_OBJECT_ACL] = oss2.OBJECT_ACL_PRIVATE
# Specify the storage class of the destination object. In this example, the storage class is set to Standard. 
# headers['x-oss-storage-class'] = oss2.BUCKET_STORAGE_CLASS_STANDARD
# Specify tags for the object. You can specify multiple tags for the object at the same time. 
# headers[OSS_OBJECT_TAGGING] = 'k1=v1&k2=v2&k3=v3'
# Specify the method that is used to configure the tag of the destination object. If you set the method to COPY, the tags of the source object are copied to the destination object. 
# headers[OSS_OBJECT_TAGGING_COPY_DIRECTIVE] = 'COPY'
# result = bucket.copy_object(src_bucket_name, src_object_name, dest_object_name, headers=headers)

# Copy the object from the source bucket to the destination bucket. 
result = bucket.copy_object(src_bucket_name, src_object_name, dest_object_name)

# View the response. If HTTP status code 200 is returned, the operation is successful. 
print('result.status:', result.status)

大きなオブジェクトをコピーする

サイズが1 GBを超えるオブジェクトをコピーするには、オブジェクトをパーツに分割し、UploadPartCopyを使用してパーツを順番にコピーする必要があります。 マルチパートコピーを実装するには、次の手順を実行します。

  1. bucket.init_multipart_uploadを使用して、マルチパートコピータスクを開始します。

  2. bucket.upload_part_copyを使用してパーツをコピーします。 最後の部分を除いて、各部分のサイズは100 KBより大きくなければなりません。

  3. plete_multipart_uploadをe bucket.comして、マルチパートコピータスクを完了します。

次のコードは、マルチパートコピーを使用して、srcexampleobject.txtという名前のオブジェクトをsrcexamplebucketからdestexamplebucket内のdestexampleobject.txtという名前のオブジェクトにコピーする方法の例を示しています。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import PartInfo
from oss2 import determine_part_size

# 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. 
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Specify the name of the source bucket. Example: srcexamplebucket. 
src_bucket_name = 'srcexamplebucket'
# Specify the name of the destination bucket. The destination bucket must be in the same region as the source bucket. Example: destexamplebucket. 
# If you copy an object within a bucket, make sure that you specify the same bucket name for the source and destination buckets.
dest_bucket_name = 'destexamplebucket'

# 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. 
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"

# If you copy an object within a bucket, comment out the line of code and change src_bucket to bucket. 
bucket = oss2.Bucket(auth, endpoint, dest_bucket_name, region=region)

src_bucket = oss2.Bucket(auth, endpoint, src_bucket_name, region=region)

# Specify the full path of the source object. Do not include the bucket name in the full path. Example: srcexampleobject.txt. 
src_object_name = 'srcexampleobject.txt'
# Specify the full path of the destination object. Do not include the bucket name in the full path. Example: destexampleobject.txt. 
dest_object_name = 'destexampleobject.txt'
# Obtain the size of the source object. If you copy an object within a bucket, change src_bucket to bucket. 
head_info = src_bucket.head_object(src_object_name)
total_size = head_info.content_length
print('src object size:', total_size)

# Use the determine_part_size method to determine the part size. 
part_size = determine_part_size(total_size, preferred_size=100 * 1024)
print('part_size:', part_size)

# Initiate a multipart upload task. 
upload_id = bucket.init_multipart_upload(dest_object_name).upload_id
parts = []

# Upload the parts. 
part_number = 1
offset = 0
while offset < total_size:
    num_to_upload = min(part_size, total_size - offset)
    end = offset + num_to_upload - 1
    # headers = dict()
    # Specify the path of the source object.     
    # headers[OSS_COPY_OBJECT_SOURCE] = '/example-bucket-by-util/recode-test.txt'
    # Specify the range of data that you want to copy. For example, if you set bytes to 0~1023, the first 1024 bytes of the source object are copied. 
    # headers[OSS_COPY_OBJECT_SOURCE_RANGE] = 'bytes=0~1023'
    # If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
    # headers['x-oss-copy-source-if-match'] = '5B3C1A2E053D763E1B002CC6****'
    # If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
    # headers['x-oss-copy-source-if-none-match'] = '5B3C1A2E053D763E1B002CC6****'
    # If the time that is specified in the request is equal to or later than the actual modified time of the object, OSS copies the object and returns 200 OK. 
    # headers['x-oss-copy-source-if-unmodified-since'] = '2021-12-09T07:01:56.000Z'
    # If the time that is specified in the request is earlier than the actual modified time of the object, OSS copies the object and returns 200 OK. 
    # headers['x-oss-copy-source-if-modified-since'] = '2021-12-09T07:01:56.000Z'
    # result = bucket.upload_part_copy(src_bucket_name, src_object_name, (offset, end), dest_object_name, upload_id, part_number, headers=headers)
    
    result = bucket.upload_part_copy(src_bucket_name, src_object_name, (offset, end), dest_object_name, upload_id, part_number)
    # Save the part information. 
    parts.append(PartInfo(part_number, result.etag))

    offset += num_to_upload
    part_number += 1

# Complete the multipart copy task. 
result = bucket.complete_multipart_upload(dest_object_name, upload_id, parts)
# View the HTTP status code in the returned response. 
print('result :', result.status)
# Query the metadata of the object. 
head_info = bucket.head_object(dest_object_name)
# Query the size of the destination object. 
dest_object_size = head_info.content_length
print('dest object size:', dest_object_size)
# Compare the size of the source and destination objects. 
assert dest_object_size == total_size

関連ドキュメント

  • 小さなオブジェクトをコピーする

    • 小さなオブジェクトのコピーに使用される完全なサンプルコードについては、GitHubをご覧ください。

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

  • 大きなオブジェクトをコピーする

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