我有一个用例,我使用多部分uplaod将数百个文件上传到我的S3存储桶。每次上传后,我需要确保上传的文件没有损坏(基本上检查数据完整性)。目前,在上传文件后,我重新下载并计算内容字符串上的md5,并将其与本地文件的md5进行比较。像
这样的东西conn = S3Connection('access key', 'secretkey')
bucket = conn.get_bucket('bucket_name')
source_path = 'file_to_upload'
source_size = os.stat(source_path).st_size
mp = bucket.initiate_multipart_upload(os.path.basename(source_path))
chunk_size = 52428800
chunk_count = int(math.ceil(source_size / chunk_size))
for i in range(chunk_count + 1):
offset = chunk_size * i
bytes = min(chunk_size, source_size - offset)
with FileChunkIO(source_path, 'r', offset=offset,
bytes=bytes) as fp:
mp.upload_part_from_file(fp, part_num=i + 1, md5=k.compute_md5(fp, bytes))
mp.complete_upload()
obj_key = bucket.get_key('file_name')
print(obj_key.md5) #prints None
print(obj_key.base64md5) #prints None
content = bucket.get_key('file_name').get_contents_as_string()
# compute the md5 on content
这种方法浪费,因为它使带宽使用量增加了一倍。我试过了
bucket.get_key('file_name').md5
bucket.get_key('file_name').base64md5
但两者都返回无。
有没有其他方法可以在不下载整个内容的情况下实现md5?
答案 0 :(得分:20)
是
使用bucket.get_key('file_name').etag[1 :-1]
这样得到密钥的MD5而不下载它的内容。
答案 1 :(得分:6)
使用boto3,我使用head_object
来检索ETag。
import boto3
import botocore
def s3_md5sum(bucket_name, resource_name):
try:
md5sum = boto3.client('s3').head_object(
Bucket=bucket_name,
Key=resource_name
)['ETag'][1:-1]
except botocore.exceptions.ClientError:
md5sum = None
pass
return md5sum
答案 2 :(得分:0)
自2016年以来,无需任何其他对象检索就可以做到这一点的最佳方法是在PutObject请求期间显示--content-md5
参数。然后,AWS将验证所提供的MD5与其计算出的MD5匹配。这也适用于分段上传和大于5GB的对象。
来自知识中心的呼叫示例:
aws s3api put-object --bucket awsexamplebucket --key awsexampleobject.txt --body awsexampleobjectpath --content-md5 examplemd5value1234567== --metadata md5checksum=examplemd5value1234567==
https://aws.amazon.com/premiumsupport/knowledge-center/data-integrity-s3/