S3如何正确执行get_object并校验MD5,跨桶上传Content-MD5不匹配如何解决
问题根因
核心原因是boto3返回的response['Body']属于StreamingBody流式对象,仅支持一次性读取:
- 第一次调用
response['Body'].read()计算MD5时,流的读取指针已经移动到末尾 - 第二次调用
response['Body'].read()作为上传的Body参数时,实际读取到的是空字节,和你之前计算的MD5自然不匹配,触发报错
修复方案
将下载到的对象内容先缓存到本地变量,计算MD5和上传操作都复用该变量即可,修改后参考代码:
import boto3 import hashlib import base64 s3 = boto3.client('s3') response = s3.get_object(Bucket='ed-test', Key='test') # 预先把内容读到变量缓存,避免二次读取流 file_content = response['Body'].read() # 用缓存内容计算MD5 md5_hash = hashlib.md5() md5_hash.update(file_content) contents_md5 = md5_hash.hexdigest() contents_md5_ = base64.b64encode(bytes.fromhex(contents_md5)).decode('utf-8') metadata = { "md5sum": contents_md5_ } # 上传时直接使用缓存的内容 s3.put_object( Body=file_content, Bucket='ed-test-2', Key='test1', Metadata=metadata, ContentMD5=contents_md5_ )
其他可排查场景
如果修改后仍有报错,可以检查以下两点:
- 如果你操作的大文件超过100MB,建议改用分片上传逻辑,此时Content-MD5的校验规则会调整为按分片计算后拼接,普通的单文件MD5计算方式不适用
- 确认源对象没有配置特殊的服务端加密规则导致get_object返回的内容和原始对象内容有差异
内容的提问来源于stack exchange,提问作者edmamerto
相关产品推荐
相关产品推荐

