既定では、既存のオブジェクトと同じ名前のオブジェクトをアップロードすると、既存のオブジェクトはアップロードされたオブジェクトによって上書きされます。 このトピックでは、x-oss-forbid-overwriteリクエストヘッダーを設定して、オブジェクトをコピーするとき、または単純なアップロードまたはマルチパートアップロードを実行するときに、既存のオブジェクトが同じ名前のオブジェクトによって上書きされないようにする方法について説明します。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。 OSSと同じリージョンにある他のAlibaba Cloudサービスを使用してObject Storage Service (OSS) にアクセスする場合は、内部エンドポイントを使用します。 OSSでサポートされているリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス資格情報は環境変数から取得します。 アクセス資格情報の設定方法の詳細については、「アクセス資格情報の設定」をご参照ください。
このトピックでは、OSSエンドポイントを使用してOSSClientインスタンスを作成します。 カスタムドメイン名またはSecurity Token Service (STS) を使用してOSSClientインスタンスを作成する場合は、「OSSClientインスタンスの作成」をご参照ください。
単純なアップロードタスクでの上書きの防止
次のサンプルコードは、単純なアップロードを実行するときに、既存のオブジェクトが同じ名前のオブジェクトによって上書きされないようにする方法の例を示しています。
com.aliyun.oss.ClientExceptionをインポートします。com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.OSSClientBuilderをインポートします。com.aliyun.oss.OSSExceptionをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.io.ByteArrayInputStreamをインポートします。public classデモ {
public static void main(String[] args) throws Exception {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケットの名前を指定します。 例: examplebucket.
String bucketName = "examplebucket";
// オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。
String objectName = "exampledir/object";
String content = "Hello OSS!";
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// PutObjectRequestオブジェクトを作成します。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName、objectName、new ByteArrayInputStream(content.getBytes()));
// 同じ名前の既存のオブジェクトを上書きするかどうかを指定します。
// デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader("x-oss-forbid-overwrite" 、"true");
putObjectRequest.setMetadata (メタデータ);
// ローカルファイルをアップロードします。
ossClient.putObject(putObjectRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "しかし、何らかの理由でエラー応答で拒否されました。");
System.out.println("エラーメッセージ:" + oe.getErrorMessage());
System.out.println("エラーコード:" + oe.getErrorCode());
System.out.println("リクエストID:" + oe.getRequestId());
System.out.println("ホストID:" + oe.getHostId());
} catch (ClientException e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
オブジェクトコピータスクでの上書きの防止
CopyObjectRequestを使用して小さなオブジェクトをコピーする
次のサンプルコードは、CopyObjectRequestを使用して小さなオブジェクトをコピーするときに、既存のオブジェクトが同じ名前の小さなオブジェクトで上書きされないようにする方法の例を示しています。
com.aliyun.oss.ClientExceptionをインポートします。com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*; com.aliyun.oss.OSSClientBuilderをインポートします。com.aliyun.oss.OSSExceptionをインポートします。com.aliyun.oss.mo delをインポートします。*; public classデモ { public static void main(String[] args) throws Exception { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // ソースバケットの名前を指定します。 文字列sourceBucketName = "srcexamplebucket"; // ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 文字列sourceObjectName = "srcexampleobject.txt"; // 宛先バケットの名前を指定します。 宛先バケットは、ソースバケットと同じリージョンに配置する必要があります。 文字列destinationBucketName = "desexamplebucket"; // 宛先オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 文字列destinationObjectName = "desexampleobject.txt"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // CopyObjectRequestオブジェクトを作成します。 CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); // 宛先オブジェクトの新しいメタデータを設定します。 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("text/html"); // 既存のオブジェクトを同じ名前で上書きするかどうかを指定します。 // デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。 metadata.setHeader("x-oss-forbid-overwrite" 、"true"); copyObjectRequest.setNewObjectMetadata (メタデータ); // オブジェクトをコピーします。 CopyObjectResult result = ossClient.copyObject(copyObjectRequest); System.out.println("ETag: " + result.getETag() + "LastModified: " + result.getLastModified()); } catch (Exception e) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "しかし、何らかの理由でエラー応答で拒否されました。"); System.out.println("エラーメッセージ:" + oe.getErrorMessage()); System.out.println("エラーコード:" + oe.getErrorCode()); System.out.println("リクエストID:" + oe.getRequestId()); System.out.println("ホストID:" + oe.getHostId()); } catch (ClientException e) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + 「ネットワークにアクセスできないなど」; System.out.println("エラーメッセージ:" + ce.getMessage()); } 最後に{ if (ossClient != null) { ossClient.shutdown(); } } } }
大きなオブジェクトをコピーする
次のサンプルコードは、マルチパートコピーを使用してラージオブジェクトをコピーするときに、既存のオブジェクトが同じ名前のラージオブジェクトによって上書きされないようにする方法の例を示しています。
com.aliyun.oss.ClientExceptionをインポートします。com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*; com.aliyun.oss.OSSClientBuilderをインポートします。com.aliyun.oss.OSSExceptionをインポートします。com.aliyun.oss.mo delをインポートします。*; java.util.ArrayListをインポートします。java.util.Listをインポートします。public classデモ { public static void main(String[] args) throws Exception { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // ソースバケットの名前を指定します。 文字列sourceBucketName = "srcexamplebucket"; // ソースオブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 文字列sourceObjectName = "srcexampleobject.txt"; // 宛先バケットの名前を指定します。 宛先バケットは、ソースバケットと同じリージョンに配置する必要があります。 文字列destinationBucketName = "desexamplebucket"; // 宛先オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 文字列destinationObjectName = "desexampleobject.txt"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName); // コピーするオブジェクトのサイズを照会します。 long contentLength = objectMetadata.getContentLength(); // 部品サイズを10 MBに設定します。 long partSize = 1024 * 1024 * 10; // Calculate the total number of parts. int partCount = (int) (contentLength / partSize); if (contentLength % partSize != 0) { partCount++; } System.out.println("total part count:" + partCount); // マルチパートコピータスクを初期化します。 InitiateMultipartUploadRequestを使用して、ターゲットオブジェクトのメタデータを指定できます。 InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationObjectName); // 既存のオブジェクトを同じ名前で上書きするかどうかを指定します。 // デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。 ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader("x-oss-forbid-overwrite" 、"true"); initiateMultipartUploadRequest.setObjectMetadata(metadata); InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest); String uploadId = initiateMultipartUploadResult.getUploadId(); // マルチパートコピータスクを開始します。 List<PartETag> partETags = new ArrayList<PartETag>(); for (int i = 0; i <recordCount; i ++ ) { // 各パーツのサイズを計算します。 long skipBytes = partSize * i; long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes; // UploadPartCopyRequestオブジェクトを作成します。 UploadPartCopyRequestを使用して条件を指定できます。 UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); uploadPartCopyRequest.setUploadId(uploadId); uploadPartCopyRequest.setPartSize(size); uploadPartCopyRequest.setBeginIndex(skipBytes); uploadPartCopyRequest.setPartNumber(i + 1); UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest); // 返されたPartETagsをpartETagsに格納します。 partETags.add(uploadPartCopyResult.getPartETag()); } // マルチパートコピータスクを完了します。 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest( destinationBucketName, destinationObjectName, uploadId, partETags); // 既存のオブジェクトを同じ名前で上書きするかどうかを指定します。 // デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。 // x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。 completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite" 、"true"); ossClient.completeMultipartUpload(completeMultipartUploadRequest); } catch (Exception e) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "しかし、何らかの理由でエラー応答で拒否されました。"); System.out.println("エラーメッセージ:" + oe.getErrorMessage()); System.out.println("エラーコード:" + oe.getErrorCode()); System.out.println("リクエストID:" + oe.getRequestId()); System.out.println("ホストID:" + oe.getHostId()); } catch (ClientException e) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + 「ネットワークにアクセスできないなど」; System.out.println("エラーメッセージ:" + ce.getMessage()); } 最後に{ if (ossClient != null) { ossClient.shutdown(); } } } }
マルチパートアップロードタスクでの上書きの防止
次のサンプルコードは、マルチパートアップロードを使用して同じ名前のオブジェクトをアップロードするときに、既存のオブジェクトが上書きされないようにする方法の例を示しています。
com.aliyun.oss.ClientExceptionをインポートします。com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.OSSClientBuilderをインポートします。com.aliyun.oss.OSSExceptionをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.io. ファイルをインポートします。java.io.FileInputStreamをインポートします。java.io.InputStreamをインポートします。java.util.ArrayListをインポートします。java.util.Listをインポートします。public classデモ {
public static void main(String[] args) throws Exception {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケットの名前を指定します。 例: examplebucket.
String bucketName = "examplebucket";
// オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。
String objectName = "exampledir/object";
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// InitiateMultipartUploadRequestオブジェクトを作成します。
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// 既存のオブジェクトを同じ名前で上書きするかどうかを指定します。
// デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader("x-oss-forbid-overwrite" 、"true");
request.setObjectMetadata (メタデータ);
// マルチパートアップロードタスクを開始します。
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// アップロードIDを取得します。 アップロードIDは、マルチパートアップロードタスクの一意の識別子です。 マルチパートアップロードタスクのキャンセルやクエリなど、アップロードIDに基づいて関連するリクエストを開始できます。
String uploadId = upresult.getUploadId();
// partETags is a set of PartETags. PartETagは、アップロードされた部品の部品番号とETagで構成されます。
List<PartETag> partETags = new ArrayList<PartETag>();
// Calculate the total number of parts.
final long partSize = 1 * 1024 * 1024L; // 1MB
final File sampleFile = new File("<localFile>");
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// すべての部品をアップロードします。
for (int i = 0; i <recordCount; i ++ ) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
InputStream instream = new FileInputStream(sampleFile);
// アップロードされたパーツをスキップします。
instream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(instream);
// 各パーツのサイズを設定します。 最後の部分を除く各部分は100 KBより大きくなければなりません。
uploadPartRequest.setPartSize(curPartSize);
// Configure part numbers. Each part is configured with a part number. The value ranges from 1 to 10000. If you configure a number beyond the range, OSS returns an InvalidArgument error code.
uploadPartRequest.setPartNumber( i + 1);
// パーツは必ずしも順番にアップロードされるとは限らず、異なるOSSクライアントからアップロードできます。 OSSは、部品番号に基づいて部品をソートし、部品を結合して完全なオブジェクトにします。
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// 部品をアップロードすると、応答にPartETagが含まれます。 The PartETag is stored in partETags.
partETags.add(uploadPartResult.getPartETag());
}
// CompleteMultipartUploadRequestオブジェクトを作成します。
// マルチパートアップロードタスクを完了したら、すべての有効なPartETagsを提供する必要があります。 OSSがPartETagsを受信すると、OSSはすべてのパーツを1つずつ検証します。 すべての部品が検証された後、OSSは部品を完全なオブジェクトに結合します。
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// 既存のオブジェクトを同じ名前で上書きするかどうかを指定します。
// デフォルトでは、x-oss-forbid-overwriteが指定されていない場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがfalseに設定されている場合、同じ名前の既存のオブジェクトが上書きされます。
// x-oss-forbid-overwriteがtrueに設定されている場合、同じ名前の既存のオブジェクトは上書きされません。 同じ名前のオブジェクトがすでに存在する場合は、エラーが報告されます。
completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite" 、"true");
// マルチパートアップロードタスクを完了します。
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "しかし、何らかの理由でエラー応答で拒否されました。");
System.out.println("エラーメッセージ:" + oe.getErrorMessage());
System.out.println("エラーコード:" + oe.getErrorCode());
System.out.println("リクエストID:" + oe.getRequestId());
System.out.println("ホストID:" + oe.getHostId());
} catch (ClientException e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
参考資料
オブジェクトアップロードシナリオで既存のオブジェクトが同じ名前のオブジェクトによって上書きされないようにする完全なサンプルコードについては、GitHubをご覧ください。
シンプルアップロードを実行するために呼び出すことができるAPI操作の詳細については、「PutObject」をご参照ください。
オブジェクトをコピーするために呼び出すことができるAPI操作の詳細については、「CopyObject」をご参照ください。
マルチパートアップロードを実行するために呼び出すことができるAPI操作の詳細については、「InitiateMultipartUpload」および「CompleteMultipartUpload」をご参照ください。