boto获取md5 s3文件

kk1*_*957 11 md5 amazon-s3 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
Run Code Online (Sandbox Code Playgroud)

这种方法浪费,因为它使带宽使用量增加了一倍.我试过了

bucket.get_key('file_name').md5 
bucket.get_key('file_name').base64md5 
Run Code Online (Sandbox Code Playgroud)

但都返回无.

有没有其他方法来实现md5而不下载整个东西?

Noa*_*amG 21

是这样
使用bucket.get_key('file_name').etag[1 :-1]
获取密钥的MD5而不下载它的内容.

  • 请注意,它仅适用于在单个部件中上载的文件.如果使用多部分下载,则etag不是MD5,您必须下载该文件才能计算哈希值 (14认同)
  • 我不同意@Beka,你可以找出亚马逊正在使用的md5而不下载文件.有关详细信息,请参阅此问题:http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3/28877788#28877788 (3认同)

gle*_*ait 7

使用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
Run Code Online (Sandbox Code Playgroud)

  • etag并不总是对象的md5哈希值. (5认同)