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

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

最終更新日:Feb 26, 2024

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

使用上の注意

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

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

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

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

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

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

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

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

# -*-コーディング: utf-8 -*-
oss2のインポート
oss2.credentialsからEnvironmentVariableCredentialsProviderをインポート

# 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# ソースバケットの名前を指定します。 例: srcexamplebucket. 
src_bucket_name = 'srcexamplebucket'
# 宛先バケットの名前を指定します。 宛先バケットは、ソースバケットと同じリージョンにある必要があります。 例: destexamplebucket。 
# バケット内のオブジェクトをコピーする場合は、送信元バケットと送信先バケットに同じバケット名を指定してください。 
dest_bucket_name = 'destexamplebucket'
# バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 
bucket = oss2.Bucket(auth, 'https:// oss-cn-hangzhou.aliyuncs.com ', dest_bucket_name)

# ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: srcexampleobject.txt。 
src_object_name = 'srcexampleobject.txt'
# 宛先オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: destexampleobject.txt。 
dest_object_name = 'destexampleobject.txt'

# headers = dict()
# CopyObject操作で同じ名前のオブジェクトを上書きするかどうかを指定します。 この例では、このパラメーターはtrueに設定されています。これは、同じ名前のオブジェクトを上書きしないことを指定します。 
# headers['x-oss-forbid-overwrite'] = 'true'
# ソースオブジェクトのパスを指定します。 
# headers[OSS_COPY_OBJECT_SOURCE] = '/example-bucket-by-util/recode-test.txt'
# ソースオブジェクトのETag値がリクエストで指定されたETag値と同じ場合、OSSはオブジェクトをコピーしてOK 200を返します。 
# headers['x-oss-copy-source-if-match'] = '5B3C1A2E053D763E1B002CC607C5 ****'
# ソースオブジェクトのETag値がリクエストで指定されたETag値と異なる場合、OSSはオブジェクトをコピーしてOK 200を返します。 
# headers['x-oss-copy-source-if-none-match'] = '5B3C1A2E053D763E1B002CC607C5 ****'
# リクエストで指定された時間がオブジェクトの実際の変更時間以降の場合、OSSはオブジェクトをコピーしてOK 200を返します。 
# headers['x-oss-copy-source-if-unmodified-since'] = '2021-12-09T07:01:56.000Z'
# リクエストで指定された時間後にソースオブジェクトが変更された場合、OSSはオブジェクトをコピーします。 
# headers['x-oss-copy-source-if-modified-since'] = '2021-12-09T07:01:56.000Z'
# 宛先オブジェクトのメタデータを構成するために使用されるメソッドを指定します。 メソッドをCOPYに設定すると、ソースオブジェクトのメタデータがターゲットオブジェクトにコピーされます。 
# headers[OSS_METADATA_DIRECTIVE] = 'COPY'
# OSSが宛先オブジェクトを作成するときに、宛先オブジェクトを暗号化するために使用されるサーバー側の暗号化アルゴリズムを指定します。 
# headers[OSS_SERVER_SIDE_ENCRYPTION] = 'KMS'
# key Management Service (KMS) が管理するカスタマーマスターキー (CMK) を指定します。 このパラメーターは、x-oss-server-side-encryptionがKMSに設定されている場合にのみ有効です。 
# headers['x-oss-server-side-encryption-key-id'] = '9468da86-3509-4f8d-a61e-6eab1eac ****'
# 宛先オブジェクトのアクセス制御リスト (ACL) を指定します。 この例では、このパラメーターはOBJECT_ACL_PRIVATEに設定されます。これは、オブジェクトの所有者と承認されたユーザーのみがオブジェクトに対する読み取りおよび書き込み権限を持っていることを示します。 
# headers[OSS_OBJECT_ACL] = oss2.OBJECT_ACL_PRIVATE
# 宛先オブジェクトのストレージクラスを指定します。 この例では、ストレージクラスはStandardに設定されています。 
# headers['x-oss-storage-classs'] = oss2.BUCKET_STORAGE_CLASS_STANDARD
# オブジェクトのタグを指定します。 オブジェクトに複数のタグを同時に指定できます。 
# headers[OSS_OBJECT_TAGGING] = 'k1=v1&k2=v2&k3=v3'
# ターゲットオブジェクトのタグを設定するために使用されるメソッドを指定します。 メソッドをCOPYに設定すると、ソースオブジェクトのタグがターゲットオブジェクトにコピーされます。 
# headers[OSS_OBJECT_TAGGING_COPY_DIRECTIVE] = 'COPY'
# result = bucket.copy_object(src_bucket_name, src_object_name, dest_object_name, headers=headers)

# オブジェクトをソースバケットから宛先バケットにコピーします。 
result = bucket.copy_object(src_bucket_name, src_object_name, dest_object_name)

# レスポンスを表示します。 HTTPステータスコード200が返された場合、操作は成功です。 
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バケットからdestexampleobject.txtという名前のオブジェクトにコピーする方法の例を示します。

# -*-コーディング: utf-8 -*-
oss2のインポート
oss2.credentialsからEnvironmentVariableCredentialsProviderをインポート
oss2.modelsからPartInfoをインポート
oss2 import determine_part_sizeから

# 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# ソースバケットの名前を指定します。 例: srcexamplebucket. 
src_bucket_name = 'srcexamplebucket'
# 宛先バケットの名前を指定します。 宛先バケットは、ソースバケットと同じリージョンにある必要があります。 例: destexamplebucket。 
# バケット内のオブジェクトをコピーする場合は、送信元バケットと送信先バケットに同じバケット名を指定してください。 
dest_bucket_name = 'destexamplebucket'
# バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 
bucket = oss2.Bucket(auth, 'https:// oss-cn-hangzhou.aliyuncs.com ', dest_bucket_name)# バケット内のオブジェクトをコピーする場合は、コード行をコメントアウトし、src_bucketをバケットに変更します。 
src_bucket = oss2.Bucket(auth, 'https:// oss-cn-hangzhou.aliyuncs.com ', src_bucket_name)

# ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: srcexampleobject.txt。 
src_object_name = 'srcexampleobject.txt'
# 宛先オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: destexampleobject.txt。 
dest_object_name = 'destexampleobject.txt'
# ソースオブジェクトのサイズを取得します。 バケット内のオブジェクトをコピーする場合は、src_bucketをバケットに変更します。 
head_info = src_bucket.head_object(src_object_name)
total_size = head_info.content_length
print('src object size:', total_size)

# determine_part_sizeメソッドを使用して、部品サイズを決定します。 
part_size = determine_part_size(total_size, preferred_size=100*1024)
プリント ('part_size:', part_size)

# マルチパートアップロードタスクを開始します。 
upload_id = bucket.init_multipart_upload(dest_object_name).upload_id
parts = []

# パーツをアップロードします。 
part_number = 1
オフセット=0
オフセット <total_size:
    num_to_upload = min(part_size, total_size - offset)
    end = offset + num_to_upload - 1
    # headers = dict()
    # ソースオブジェクトのパスを指定します。     
    # headers[OSS_COPY_OBJECT_SOURCE] = '/example-bucket-by-util/recode-test.txt'
    # コピーするデータの範囲を指定します。 たとえば、バイト数を0 ~ 1023に設定すると、ソースオブジェクトの最初の1024バイトがコピーされます。 
    # headers[OSS_COPY_OBJECT_SOURCE_RANGE] = 'bytes=0 ~ 1023'
    # ソースオブジェクトのETag値がリクエストで指定されたETag値と同じ場合、OSSはオブジェクトをコピーしてOK 200を返します。 
    # headers['x-oss-copy-source-if-match'] = '5B3C1A2E053D763E1B002CC6 ****'
    # ソースオブジェクトのETag値がリクエストで指定されたETag値と異なる場合、OSSはオブジェクトをコピーしてOK 200を返します。 
    # headers['x-oss-copy-source-if-none-match'] = '5B3C1A2E053D763E1B002CC6 ****'
    # リクエストで指定された時間がオブジェクトの実際の変更時間以降の場合、OSSはオブジェクトをコピーしてOK 200を返します。 
    # headers['x-oss-copy-source-if-unmodified-since'] = '2021-12-09T07:01:56.000Z'
    # リクエストで指定された時刻がオブジェクトの実際の変更時刻より前の場合、OSSはオブジェクトをコピーしてOK 200を返します。 
    # 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)
    # パーツ情報を保存します。 
    parts.append(PartInfo(part_number, result.etag))

    offset += num_to_upload
    part_number += 1

# マルチパートコピータスクを完了します。 
result = bucket.com plete_multipart_upload(dest_object_name, upload_id, parts)
# 返されたレスポンスのHTTPステータスコードを表示します。 
print('result :', result.status)
# オブジェクトのメタデータを照会します。 
head_info = bucket.head_object(dest_object_name)
# 宛先オブジェクトのサイズを照会します。 
dest_object_size = head_info.content_length
print('dest object size:', dest_object_size)
# ソースオブジェクトと宛先オブジェクトのサイズを比較します。 
assert dest_object_size == total_size 

参考資料

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

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

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

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

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