オブジェクトの内容を変更することなく、同じリージョン内のソースのクラウドボックスの OSS バケットから宛先のクラウドボックスの OSS バケットにオブジェクトをコピーできます。このプロセスは、データバックアップ、配信、ディザスタリカバリなどのユースケースをサポートします。これにより、データの可用性と冗長性が向上し、バケット間のデータ整合性とセキュリティが確保されます。宛先バケットはソースバケットと同じリージョンにある必要があります。CloudBox は、Alibaba Cloud が提供する効率的で信頼性の高いデータストレージおよび管理サービスです。
制限事項
リージョンをまたいでオブジェクトをコピーすることはできません。たとえば、中国 (杭州) リージョンのバケットから中国 (上海) リージョンのバケットにオブジェクトをコピーすることはできません。
使用上の注意
ソースオブジェクトに対する読み取り権限と、宛先バケットに対する読み取りおよび書き込み権限が必要です。そうでない場合、コピー操作は失敗します。
デフォルトでは、オブジェクトをコピーすると、宛先バケット内の同じ名前の既存のオブジェクトが上書きされます。オブジェクトが誤って上書きされるのを防ぐには、次のいずれかの方法を使用します。
バージョン管理を有効にする
上書きまたは削除されたオブジェクトは履歴バージョンとして保存されます。いつでも復元できます。詳細については、「CloudBox のバージョン管理」をご参照ください。
コピーリクエストに x-oss-forbid-overwrite ヘッダーを含める
コピーリクエストに x-oss-forbid-overwrite ヘッダーを含め、ヘッダーを true に設定してオブジェクトの上書きを無効にすることができます。宛先バケット内の既存のオブジェクトと同じ名前のオブジェクトをコピーすると、オブジェクトのコピーに失敗し、
FileAlreadyExistsエラーコードが返されます。
小さいオブジェクトのコピー
CopyObject API 操作を呼び出すことで、クラウドボックスの OSS 内の 1 GB 未満のオブジェクトをコピーできます。
OSS SDK for Java の使用
オブジェクトをコピーできるのは、Object Storage Service (OSS) SDK for Java 3.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 {
// クラウドボックスの 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 バケットが配置されているリージョンを指定します。
String region = "cn-hangzhou";
// CloudBox の ID を指定します。
String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
// ソースのクラウドボックスの OSS バケットの名前を指定します。
String sourceBucketName = "srcexamplebucket";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。
String sourceKey = "srcexampleobject.txt";
// ソースバケットと同じリージョンにある宛先のクラウドボックスの OSS バケットの名前を指定します。
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");
// 同じ名前を持つ場合に宛先オブジェクトを上書きするかどうかを指定します。この例では、このパラメーターは true に設定され、上書きが禁止されます。
// meta.setHeader("x-oss-forbid-overwrite", "true");
// コピー操作のソースパスを指定します。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
// ソースオブジェクトの ETag が指定した ETag と一致する場合、コピー操作が実行され、200 OK が返されます。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// ソースオブジェクトの ETag が指定した ETag と一致しない場合、コピー操作が実行され、200 OK が返されます。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// 指定された時刻がオブジェクトの実際の変更時刻と同じかそれより後の場合、オブジェクトがコピーされ、200 OK が返されます。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// 指定した時刻の後にソースオブジェクトが変更された場合、コピー操作が実行されます。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// 宛先オブジェクトのメタデータの設定方法を指定します。この例では、このパラメーターは COPY に設定され、ソースオブジェクトから宛先オブジェクトにメタデータをコピーします。
// meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
// 宛先オブジェクトの作成時に OSS が使用するサーバ側暗号化アルゴリズムを指定します。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
// KMS によって管理されるカスタマーマスターキー (CMK) を指定します。このパラメーターは、x-oss-server-side-encryption が KMS に設定されている場合にのみ有効です。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
// OSS で宛先オブジェクトが作成されるときのアクセス権限を指定します。この例では、このパラメーターは Private に設定されています。これは、オブジェクト所有者と承認されたユーザーのみがオブジェクトに対する読み取りおよび書き込み権限を持つことを意味します。他のユーザーはオブジェクトにアクセスできません。
// meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
// オブジェクトのストレージタイプを指定します。この例では、このパラメーターは Standard に設定されています。
// meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
// オブジェクトタグを指定します。複数のタグを同時に指定できます。
// 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 を使用して小さいオブジェクトをコピーする方法の詳細については、「cp (ファイルのコピー)」をご参照ください。
大きいオブジェクトのコピー
UploadPartCopy API 操作を呼び出すことで、クラウドボックスの OSS 内の 1 GB を超えるオブジェクトをコピーできます。
OSS SDK for Java の使用
オブジェクトをコピーできるのは、OSS SDK for Java 3.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 {
// クラウドボックスの 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 バケットが配置されているリージョンを指定します。
String region = "cn-hangzhou";
// CloudBox の ID を指定します。
String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
// ソースのクラウドボックスの OSS バケットの名前を指定します。
String sourceBucketName = "srcexamplebucket";
// ソースオブジェクトの完全なパスを指定します。完全なパスにバケット名を含めることはできません。
String sourceKey = "srcexampleobject.txt";
// ソースバケットと同じリージョンにある宛先のクラウドボックスの OSS バケットの名前を指定します。
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 を使用して大きいオブジェクトをコピーする方法の詳細については、「cp (ファイルのコピー)」をご参照ください。
REST API の使用
プログラムで大幅なカスタマイズが必要な場合は、REST API リクエストを直接作成できます。REST API リクエストを作成するには、署名を計算するコードを手動で記述する必要があります。詳細については、「UploadPartCopy」をご参照ください。