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

Object Storage Service:データ検証 (Java SDK V1)

最終更新日:Nov 26, 2025

Object Storage Service (OSS) は、オブジェクトのアップロード、ダウンロード、コピー時にデータ整合性を確保するため、データ検証用に MD5 と 64 ビット巡回冗長検査 (CRC-64) を提供します。

注意事項

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

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

  • このトピックでは、OSS エンドポイントを使用して OSSClient インスタンスを作成します。 カスタムドメイン名または Security Token Service (STS) を使用して OSSClient インスタンスを作成する場合は、一般的なシナリオの設定例をご参照ください。

MD5 検証

ファイルをアップロードする際、Content-MD5 ヘッダーを設定してデータ整合性を確保できます。 OSS は受信したコンテンツの MD5 ハッシュを計算します。 OSS が計算した MD5 ハッシュが、指定された MD5 ハッシュと一致しない場合、OSS は InvalidDigest エラーを返します。 このエラーが発生した場合は、ファイルを再度アップロードする必要があります。

MD5 検証は、マルチパートアップロードでもサポートされています。 マルチパートアップロードの場合、MD5 検証は各パートに対して実行されます。 これを行うには、UploadPartRequest の setMd5Digest メソッドを呼び出して、クライアントで計算されたパートの MD5 ハッシュを設定します。

説明

putObject、getObject、appendObject、postObject、マルチパートアップロード、および uploadPart 操作で MD5 検証がサポートされています。

  • ファイルをアップロードする際に MD5 検証を実行する:

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.common.utils.BinaryUtil;
    import com.aliyun.oss.model.ObjectMetadata;
    import java.io.ByteArrayInputStream;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // この例では、中国 (杭州) リージョンのエンドポイントを使用します。 実際の値に置き換えてください。
            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";
            // バケットが配置されているリージョンを指定します。 この例では、中国 (杭州) リージョンのバケットに cn-hangzhou を使用します。
            String region = "cn-hangzhou";
    
            // OSSClient インスタンスを作成します。
            // OSSClient インスタンスが不要になったら、shutdown メソッドを呼び出してリソースを解放します。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            try {
                // 文字列をアップロードします。
                String content = "Hello OSS";
    
                ObjectMetadata meta = new ObjectMetadata();
                // MD5 検証を設定します。
                String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
                meta.setContentMD5(md5);
    
                ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta);
    
            } 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();
                }
            }
        }
    }            
  • マルチパートアップロードで MD5 検証を実行する:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.aliyun.oss.ClientBuilderConfiguration;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.common.auth.CredentialsProviderFactory;
    import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.common.utils.BinaryUtil;
    import com.aliyun.oss.model.CompleteMultipartUploadRequest;
    import com.aliyun.oss.model.CompleteMultipartUploadResult;
    import com.aliyun.oss.model.InitiateMultipartUploadRequest;
    import com.aliyun.oss.model.InitiateMultipartUploadResult;
    import com.aliyun.oss.model.PartETag;
    import com.aliyun.oss.model.UploadPartRequest;
    import com.aliyun.oss.model.UploadPartResult;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            // この例では、中国 (杭州) リージョンのエンドポイントを使用します。 実際の値に置き換えてください。
            String endpoint = "http://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 localFile = "D:\\localpath\\examplefile.txt";
            // バケットが配置されているリージョンを指定します。 この例では、中国 (杭州) リージョンのバケットに cn-hangzhou を使用します。
            String region = "cn-hangzhou";
    
            // OSSClient インスタンスを作成します。
            // OSSClient インスタンスが不要になったら、shutdown メソッドを呼び出してリソースを解放します。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
            // InitiateMultipartUploadRequest オブジェクトを作成します。
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
            // マルチパートアップロードを初期化する際にストレージクラスを設定するには、次のサンプルコードをご参照ください。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // request.setObjectMetadata(metadata);
            // マルチパートアップロードを初期化します。
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            // アップロード ID が返されます。 アップロード ID は、マルチパートアップロードイベントを一意に識別します。 アップロード ID を使用して、マルチパートアップロードのキャンセルやパートのクエリなどの操作を実行できます。
            String uploadId = upresult.getUploadId();
            // partETags は PartETag オブジェクトのコレクションです。 PartETag オブジェクトは、パートの ETag とパート番号で構成されます。
            List<PartETag> partETags = new ArrayList<PartETag>();
            // パート数を計算します。
            final long partSize = 1 * 1024 * 1024L;   // 1 MB
            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 < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
                InputStream instream = new FileInputStream(sampleFile);
                InputStream instream1 = new FileInputStream(sampleFile);
             // アップロード済みのパートをスキップします。
                instream.skip(startPos);
                instream1.skip(startPos);
                String md5;
                if(i==partCount-1){
             // 注意: 最後のパートでは、データはパートのサイズではなく、ファイルの終わりまで読み取られます。
                    md5 = md5(instream1,fileLength - startPos);
                }else{
                    md5 = md5(instream1,partSize);
                }
              // instream1.skip(n)
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(instream);
                uploadPartRequest.setMd5Digest(md5);
             // パートサイズを設定します。 最後のパートを除き、パートの最小サイズは 100 KB です。
                uploadPartRequest.setPartSize(curPartSize);
             // パート番号を設定します。 アップロードされる各パートには、1 から 10,000 までの範囲のパート番号があります。 パート番号がこの範囲にない場合、OSS は InvalidArgument エラーを返します。
                uploadPartRequest.setPartNumber( i + 1);
             // パートを順番にアップロードする必要はありません。 異なるクライアントからパートをアップロードすることもできます。 OSS は、パート番号に基づいてパートを完全なファイルに結合します。
                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
             // System.out.println("server md5" +uploadPartResult.getETag());
             // 各パートがアップロードされると、OSS は PartETag を含む結果を返します。 PartETag は partETags に格納されます。
                partETags.add(uploadPartResult.getPartETag());
            }
            // CompleteMultipartUploadRequest オブジェクトを作成します。
            // マルチパートアップロードを完了する際には、すべての有効な partETags を提供する必要があります。 OSS は送信された partETags を受信した後、各パートの有効性を検証します。 すべてのパートが検証された後、OSS はそれらを完全なファイルに結合します。
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
            // マルチパートアップロードを完了する際にファイルのアクセス権限を設定するには、次のサンプルコードをご参照ください。
            // completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead);
            // アップロードを完了します。
            CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            // OSSClient をシャットダウンします。
            ossClient.shutdown();
        }
        public static String md5(InputStream in , long length1) throws Exception{
            byte[] bytes = new byte[(int) length1];
            long length_tmp = length1;
            int readSize = in.read(bytes, (int) 0, (int) length_tmp);
            return BinaryUtil.toBase64String(BinaryUtil.calculateMd5(bytes));
        }
    }

CRC-64 検証

デフォルトでは、データ整合性を確保するために、ファイルのアップロード、ダウンロード、およびコピー操作で CRC-64 データ検証が有効になっています。

説明
  • putObject、getObject、appendObject、および uploadPart 操作は CRC-64 検証をサポートしています。 デフォルトでは、アップロードに対して CRC-64 検証が有効になっています。 クライアントで計算された CRC 値がサーバーから返された CRC 値と異なる場合、InconsistentException エラーがスローされます。

  • 範囲ダウンロードは CRC-64 検証をサポートしていません。

  • CRC-64 検証は CPU リソースを消費するため、アップロードおよびダウンロードの速度に影響を与える可能性があります。

  • ファイルをダウンロードする際に CRC-64 検証を実行する:

    次のコードは、ファイルをダウンロードする際に CRC-64 を使用してデータ整合性を検証する方法を示しています:

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.common.utils.IOUtils;
    import com.aliyun.oss.internal.OSSHeaders;
    import com.aliyun.oss.internal.OSSUtils;
    import com.aliyun.oss.model.GetObjectRequest;
    import com.aliyun.oss.model.OSSObject;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // この例では、中国 (杭州) リージョンのエンドポイントを使用します。 実際の値に置き換えてください。
            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";
            // バケットが配置されているリージョンを指定します。 この例では、中国 (杭州) リージョンのバケットに cn-hangzhou を使用します。
            String region = "cn-hangzhou";
    
            // OSSClient インスタンスを作成します。
            // OSSClient インスタンスが不要になったら、shutdown メソッドを呼び出してリソースを解放します。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            try {
                // ストリーミングダウンロードを実行します。
                GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
                OSSObject ossObject = ossClient.getObject(bucketName, objectName);
    
                // ファイルの内容を読み取ります。 clientCrc は、ファイルの内容を読み取った後にのみ取得できます。
                System.out.println("Object content:");
                BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
                while (true) {
                    String line = reader.readLine();
                    if (line == null) break;
    
                    System.out.println("\n" + line);
                }
                // データの読み取り後、ストリームを閉じる必要があります。 そうしないと、接続リークが発生する可能性があります。 これにより、プログラムが利用可能な接続を使い果たし、動作を停止する原因となります。
                reader.close();
    
                // クライアントで CRC 検証が有効になっているかどうかを確認します。 デフォルトでは有効です。
                Boolean isCrcCheckEnabled = ((OSSClient)ossClient).getClientConfiguration().isCrcCheckEnabled();
                // リクエストが範囲ダウンロードであるかどうかを確認します。 範囲ダウンロードは CRC 検証をサポートしていません。
                Boolean isRangGetRequest = getObjectRequest.getHeaders().get(OSSHeaders.RANGE) != null;
    
                // CRC を検証します。 clientCRC は、ファイルの内容を読み取った後にのみ取得できます。
                if (isCrcCheckEnabled && !isRangGetRequest) {
                    Long clientCRC = IOUtils.getCRCValue(ossObject.getObjectContent());
                    OSSUtils.checkChecksum(clientCRC, ossObject.getServerCRC(), ossObject.getRequestId());
                }
            } 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();
                }
            }
        }
    }
  • 追加アップロードで CRC-64 検証を実行する:

    次のコードは、追加アップロードでデータ整合性を検証するために CRC-64 を使用する方法を示しています:

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.model.*;
    import java.io.ByteArrayInputStream;
    
    public class Demo {
          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";
              // オブジェクトの完全なパス (例: exampleobject.txt) を指定します。 完全なパスにバケット名を含めることはできません。
              String objectName = "exampleobject.txt";
              // 最初の追加操作のコンテンツを指定します。 例: Hello。
              String firstAppendContent = "Hello";
              // 2 番目の追加操作のコンテンツを指定します。 例: World。
              String secondAppendContent = "World";        
              // バケットが配置されているリージョンを指定します。 この例では、中国 (杭州) リージョンのバケットに cn-hangzhou を使用します。
              String region = "cn-hangzhou";
      
              // OSSClient インスタンスを作成します。
              // OSSClient インスタンスが不要になったら、shutdown メソッドを呼び出してリソースを解放します。
              ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
              clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
              OSS ossClient = OSSClientBuilder.create()
              .endpoint(endpoint)
              .credentialsProvider(credentialsProvider)
              .clientConfiguration(clientBuilderConfiguration)
              .region(region)               
              .build();
      
              try {
                  // 最初の追加操作を実行します。
                  AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(firstAppendContent.getBytes()));
                  appendObjectRequest.setPosition(0L);
                  // CRC を初期化します。 初期化後、SDK はデフォルトでアップロード結果に対して CRC 検証を実行します。
                  appendObjectRequest.setInitCRC(0L);
                  AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest);
      
                  // 2 番目の追加操作を実行します。
                  appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(secondAppendContent.getBytes()));
                  appendObjectRequest.setPosition(appendObjectResult.getNextPosition());
                  // 初期 CRC をアップロード済みデータの CRC に設定します。 初期化後、SDK はデフォルトでアップロード結果に対して CRC 検証を実行します。
                  appendObjectRequest.setInitCRC(appendObjectResult.getClientCRC());
                  ossClient.appendObject(appendObjectRequest);
              } 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();
                  }
              }
          }
    }

関連ドキュメント

データ検証の完全なサンプルコードについては、GitHub の例をご参照ください。