You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用校验和验证AWS S3文件上传成功及本地与S3文件一致性?

利用校验和验证S3文件上传及一致性校验

一、上传阶段启用校验和验证

AWS S3支持MD5、SHA-256等多种校验和算法,上传时可主动传递本地计算的校验和,让S3自动对比自身计算的结果,若不一致则返回错误,以此验证上传是否成功。

1. 先实现本地文件校验和计算工具

import java.io.FileInputStream;
import java.security.MessageDigest;
import java.util.Base64;

public class ChecksumUtils {
    // 计算文件MD5校验和(Base64编码,匹配S3的Content-MD5格式)
    public static String calculateMD5(String filePath) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int readLen;
            while ((readLen = fis.read(buffer)) != -1) {
                md.update(buffer, 0, readLen);
            }
        }
        return Base64.getEncoder().encodeToString(md.digest());
    }

    // 计算文件SHA-256校验和(更高安全性)
    public static String calculateSHA256(String filePath) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int readLen;
            while ((readLen = fis.read(buffer)) != -1) {
                md.update(buffer, 0, readLen);
            }
        }
        return Base64.getEncoder().encodeToString(md.digest());
    }
}

2. 修改上传代码,添加校验和验证逻辑

public class S3Uploader {

    @Autowired
    private S3TransferManager transferManager;

    public String uploadFile(String bucketName, String key, String filePath) throws Exception {
        // 计算本地文件MD5
        String localMD5 = ChecksumUtils.calculateMD5(filePath);

        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
                .putObjectRequest(b -> b
                        .bucket(bucketName)
                        .key(key)
                        // 传递本地MD5,S3会自动对比校验
                        .contentMD5(localMD5))
                .addTransferListener(LoggingTransferListener.create())
                .source(Paths.get(filePath))
                .build();

        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
        // 若校验失败,completionFuture().join()会抛出SdkException
        CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
        
        return uploadResult.response().eTag();
    }
}

说明:如果S3计算的校验和与你传递的不一致,会直接抛出异常,此时可判定上传失败。

二、上传后校验本地与S3文件的一致性

上传完成后,可主动获取S3文件的校验和,与本地文件的校验和对比,确认文件一致。

方式1:通过S3文件元数据获取校验和对比

import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
import software.amazon.awssdk.services.s3.model.HeadObjectResponse;

@Autowired
private S3Client s3Client;

public boolean verifyFileConsistency(String bucketName, String key, String localFilePath) throws Exception {
    // 计算本地文件MD5
    String localMD5 = ChecksumUtils.calculateMD5(localFilePath);

    // 获取S3文件的MD5校验和
    HeadObjectRequest headReq = HeadObjectRequest.builder()
            .bucket(bucketName)
            .key(key)
            .build();
    HeadObjectResponse headResp = s3Client.headObject(headReq);
    String s3MD5 = headResp.contentMD5();

    // 对比校验和
    return localMD5.equals(s3MD5);
}

如果使用SHA-256,上传时需在PutObjectRequest中调用.checksumSHA256(localSHA256),获取时从headResp.checksumSHA256()取值对比即可。

方式2:利用ETag对比(仅限单文件非分块上传场景)

普通单文件上传时,S3返回的ETag等于文件MD5(需去掉前后引号),但分块上传时ETag是分块MD5的组合值,无法直接对比。若确认是单文件上传,可使用此方式:

public boolean verifyWithETag(String bucketName, String key, String localFilePath) throws Exception {
    String localMD5 = ChecksumUtils.calculateMD5(localFilePath);
    // 去掉ETag的前后引号
    String s3ETag = s3Client.headObject(HeadObjectRequest.builder().bucket(bucketName).key(key).build())
            .eTag().replace("\"", "");
    return localMD5.equals(s3ETag);
}

关键注意事项

  • 分块上传场景:分块上传的ETag不等于单个文件MD5,必须使用S3返回的checksumMD5或checksumSHA256进行对比。
  • 算法选择:追求更高安全性优先选SHA-256,MD5适合普通校验场景。
  • 异常处理:计算校验和、请求S3时可能抛出IO或SDK异常,需自行捕获处理。

内容的提问来源于stack exchange,提问作者Pale Blue Dot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:45:09