オブジェクトのコンテンツを変更することなく、同じリージョン内の CloudBox バケット上のソース Object Storage Service (OSS) から宛先 OSS on CloudBox バケットにオブジェクトをコピーできます。このオブジェクトコピー機能により、データのバックアップ、配布、および障害復旧が可能になります。オブジェクトをコピーすることで、データの可用性と冗長性を高めながら、バケット全体のデータの整合性とセキュリティを確保できます。CloudBox は、Alibaba Cloud が提供する効率的で信頼性の高いデータストレージおよび管理サービスです。
制限
異なるリージョンにある OSS on CloudBox バケット間でオブジェクトをコピーすることはできません。たとえば、中国 (杭州) リージョンのバケットから中国 (上海) リージョンのバケットにオブジェクトをコピーすることはできません。
使用上の注意
ソースオブジェクトに対する読み取り権限と、宛先バケットに対する読み取りおよび書き込み権限が必要です。そうでない場合、コピー操作は失敗します。
デフォルトでは、宛先パスにある既存のオブジェクトと同じ名前のオブジェクトをコピーすると、コピーされたオブジェクトは宛先パスにある既存のオブジェクトを上書きします。次のいずれかの方法を使用して、オブジェクトが予期せず上書きされないように保護できます。
宛先バケットのバージョニングを有効にする
宛先バケットでバージョニングが有効になっている場合、上書きされたオブジェクトは以前のバージョンとして保存されます。いつでもオブジェクトを以前のバージョンに復元できます。詳細については、「バージョニング」をご参照ください。
x-oss-forbid-overwrite ヘッダーをコピーリクエストに含める
x-oss-forbid-overwrite ヘッダーをコピーリクエストに含め、ヘッダーを true に設定して、オブジェクトの上書きを無効にすることができます。宛先バケットにある既存のオブジェクトと同じ名前のオブジェクトをコピーすると、オブジェクトのコピーに失敗し、
FileAlreadyExists
エラーコードが返されます。
小さいオブジェクトをコピーする
OSS on CloudBox では、CopyObject 操作を呼び出すことで、1 GB 未満のオブジェクトをコピーできます。
OSS SDK for Java を使用する
OSS SDK for Java V3.15.0 以降のみを使用してオブジェクトをコピーできます。次のサンプルコードは、小さいオブジェクトをコピーします。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
public class Demo {
public static void main(String[] args) throws Exception {
// CloudBox バケット上の OSS のデータエンドポイントを指定します。
String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
// 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// ソースと宛先の OSS on CloudBox バケットが配置されているリージョンを指定します。
String region = "cn-hangzhou";
// クラウドボックスの ID を指定します。
String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
// ソース OSS on CloudBox バケットの名前を指定します。
String sourceBucketName = "srcexamplebucket";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
String sourceKey = "srcexampleobject.txt";
// ソース OSS on CloudBox バケットと同じリージョンにある宛先 OSS on CloudBox バケットの名前を指定します。
String destinationBucketName = "desexamplebucket";
// 宛先オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
String destinationKey = "desexampleobject.txt";
// OSSClient インスタンスを作成します。
// OSSClient が不要になったら、shutdown メソッドを呼び出してリソースを解放します。
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
conf.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(new DefaultCredentialProvider(credentialsProvider.getCredentials()))
.clientConfiguration(conf)
.region(region)
.cloudBoxId(cloudBoxId)
.build();
try {
// CopyObjectRequest オブジェクトを作成します。
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
// 新しいオブジェクトメタデータを指定します。
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("text/txt");
// CopyObject 操作で同じ名前の既存のオブジェクトを上書きするかどうかを指定します。この例では、このパラメーターは true に設定されています。これは、CopyObject 操作で同じ名前の既存のオブジェクトを上書きしないことを指定します。
// meta.setHeader("x-oss-forbid-overwrite", "true");
// ソースオブジェクトのパスを指定します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
// ソースオブジェクトの ETag 値がリクエストで指定された ETag 値と同じである場合、OSS はオブジェクトをコピーし、200 OK を返します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// ソースオブジェクトの ETag 値がリクエストで指定された ETag 値と異なる場合、OSS はオブジェクトをコピーし、200 OK を返します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// リクエストで指定された時刻がオブジェクトの変更時刻と同じかそれ以降の場合、OSS はオブジェクトをコピーし、200 OK を返します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// リクエストで指定された時刻より後にソースオブジェクトが変更された場合、OSS はオブジェクトをコピーします。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// 宛先オブジェクトのメタデータを構成するために使用されるメソッドを指定します。この例では、メソッドは COPY に設定されています。これは、ソースオブジェクトのメタデータが宛先オブジェクトにコピーされることを指定します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
// オブジェクトの作成時に宛先オブジェクトの暗号化に使用されるサーバー側暗号化アルゴリズムを指定します。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
// Key Management Service (KMS) によって管理されるカスタマーマスターキー (CMK) を指定します。このパラメーターは、x-oss-server-side-encryption を KMS に設定した場合にのみ有効になります。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
// 宛先オブジェクトのアクセス制御リスト (ACL) を指定します。この例では、ACL は private に設定されています。これは、オブジェクト所有者と承認されたユーザーのみがオブジェクトに対する読み取りおよび書き込み権限を持つことを指定します。
// meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
// 宛先オブジェクトのストレージクラスを指定します。この例では、ストレージクラスは Standard に設定されています。
// meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
// 宛先オブジェクトに 1 つ以上のタグを指定します。
// meta.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
// 宛先オブジェクトのタグを構成するために使用されるメソッドを指定します。この例では、メソッドは COPY に設定されています。これは、ソースオブジェクトのタグが宛先オブジェクトにコピーされることを指定します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_TAGGING_DIRECTIVE, "COPY");
copyObjectRequest.setNewObjectMetadata(meta);
// オブジェクトをコピーします。
CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
ossutil を使用する
ossutil を使用して、1 GB 未満のオブジェクトをコピーできます。詳細については、「オブジェクトのコピー」をご参照ください。
大きいオブジェクトをコピーする
OSS on CloudBox では、UploadPartCopy 操作を呼び出すことで、1 GB を超えるオブジェクトをコピーできます。
OSS SDK for Java を使用する
OSS SDK for Java V3.15.0 以降のみを使用してオブジェクトをコピーできます。次のサンプルコードは、大きいオブジェクトをコピーします。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import java.util.ArrayList;
import java.util.List;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
public class Demo {
public static void main(String[] args) throws Exception {
// CloudBox バケット上の OSS のデータエンドポイントを指定します。
String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
// 環境変数からアクセス認証情報を取得します。サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// ソースと宛先の OSS on CloudBox バケットが配置されているリージョンを指定します。
String region = "cn-hangzhou";
// クラウドボックスの ID を指定します。
String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
// ソース OSS on CloudBox バケットの名前を指定します。
String sourceBucketName = "srcexamplebucket";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
String sourceKey = "srcexampleobject.txt";
// ソース OSS on CloudBox バケットと同じリージョンにある宛先 OSS on CloudBox バケットの名前を指定します。
String destinationBucketName = "desexamplebucket";
// 宛先オブジェクトの完全なパスを指定します。完全なパスにバケット名を含めないでください。
String destinationKey = "desexampleobject.txt";
// OSSClient インスタンスを作成します。
// OSSClient が不要になったら、shutdown メソッドを呼び出してリソースを解放します。
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
conf.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(new DefaultCredentialProvider(credentialsProvider.getCredentials()))
.clientConfiguration(conf)
.region(region)
.cloudBoxId(cloudBoxId)
.build();
try {
ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceKey);
// ソースオブジェクトのサイズをクエリします。
long contentLength = objectMetadata.getContentLength();
// パートサイズをバイト単位で設定します。この例では、パートサイズは 10 MB に設定されています。
long partSize = 1024 * 1024 * 10;
// パートの総数を計算します。
int partCount = (int) (contentLength / partSize);
if (contentLength % partSize != 0) {
partCount++;
}
System.out.println("total part count:" + partCount);
// マルチパートコピータスクを開始します。InitiateMultipartUploadRequest を使用して宛先オブジェクトのメタデータを指定します。
InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationKey);
InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
String uploadId = initiateMultipartUploadResult.getUploadId();
// マルチパートコピータスクを開始します。
List<PartETag> partETags = new ArrayList<PartETag>();
for (int i = 0; i < partCount; i++) {
// パートサイズを計算します。
long skipBytes = partSize * i;
long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
// UploadPartCopyRequest オブジェクトを作成します。UploadPartCopyRequest を使用して条件を指定できます。
UploadPartCopyRequest uploadPartCopyRequest =
new UploadPartCopyRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
uploadPartCopyRequest.setUploadId(uploadId);
uploadPartCopyRequest.setPartSize(size);
uploadPartCopyRequest.setBeginIndex(skipBytes);
uploadPartCopyRequest.setPartNumber(i + 1);
UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
// 返されたパート ETag を partETags に保存します。
partETags.add(uploadPartCopyResult.getPartETag());
}
// マルチパートコピータスクを完了します。
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
destinationBucketName, destinationKey, uploadId, partETags);
ossClient.completeMultipartUpload(completeMultipartUploadRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
ossutil を使用する
ossutil を使用して、1 GB を超えるオブジェクトをコピーできます。詳細については、「オブジェクトのコピー」をご参照ください。
OSS API を使用する
ビジネスで高度なカスタマイズが必要な場合は、RESTful API を直接呼び出すことができます。API を直接呼び出すには、コードに署名計算を含める必要があります。詳細については、「UploadPartCopy」をご参照ください。