2014-10-17 7 views
5

У меня есть прецедент, в котором я загружаю сотни файлов в свой ведро S3, используя многоуровневую uplaod. После каждой загрузки мне нужно убедиться, что загруженный файл не поврежден (в основном проверьте целостность данных). В настоящее время после загрузки файла я повторно загружаю его и вычисляю md5 в строке содержимого и сравниваю его с md5 локального файла. Так что-то вродеboto get md5 s3 file

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 без загрузки всего этого?

ответ

13

да
использование bucket.get_key('file_name').etag[1 :-1]
таким образом получить MD5 ключа без загрузки его содержимое.

+12

Обратите внимание, что это относится только к файлам, которые были загружены в одну часть. Если вы используете многостраничную загрузку, etag не является MD5, и вы должны скачать файл, чтобы рассчитать хеш – Beka

+0

Спасибо @Beka не знал, что – NoamG

+2

Я не согласен @Beka, вы можете выяснить, md5, который использует Amazon без загружая файл. Для получения дополнительной информации см. Этот вопрос: http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3/28877788#28877788 – Spedge

2

С помощью 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

. Этог не всегда является хешем md5 объекта. – algal

Смежные вопросы