2014-10-17 20 views
5

Ho un caso d'uso in cui carico centinaia di file sul mio secchio S3 usando un multi-up uplaod. Dopo ogni upload, devo assicurarmi che il file caricato non sia corrotto (in pratica controlla l'integrità dei dati). Attualmente, dopo aver caricato il file, lo scarico nuovamente e computo l'md5 sulla stringa del contenuto e lo confronta con l'md5 del file locale. Quindi qualcosa comeboto 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 

Questo approccio è dispendioso poiché raddoppia l'utilizzo della larghezza di banda. Ho provato

bucket.get_key('file_name').md5 
bucket.get_key('file_name').base64md5 

ma entrambi restituiscono Nessuno.

C'è qualche altro modo per ottenere md5 senza scaricare il tutto?

risposta

13


uso bucket.get_key('file_name').etag[1 :-1]
questo modo ottenere MD5 di chiavi senza scaricare il suo contenuto.

+12

Si noti che è corretto solo per i file che sono stati caricati in una singola parte. Se usi il download multipart, etag non è l'MD5 e devi scaricare il file per calcolare l'hash – Beka

+0

Grazie @Beka non sapevo che – NoamG

+2

Non sono d'accordo @Beka, puoi capire il md5 che Amazon usa senza scaricare il file. Per ulteriori informazioni, vedere questa domanda: http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3/28877788#28877788 – Spedge

2

Con boto3, utilizzo head_object per recuperare l'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

L'etag non è sempre l'hash MD5 di un oggetto. – algal

Problemi correlati