boto获取md5 s3文件

时间:2014-10-17 00:10:36

标签: amazon-s3 md5 boto

我有一个用例,我使用多部分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?

3 个答案:

答案 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/