2014-10-17 12 views
5

Ich habe einen Anwendungsfall, wo ich hunderte von Datei auf meine S3-Bucket hochladen mit mehreren Teilen uplaod. Nach jedem Upload muss sichergestellt werden, dass die hochgeladene Datei nicht beschädigt ist (grundsätzlich auf Datenintegrität prüfen). Momentan, nach dem Hochladen der Datei, lade ich sie erneut herunter und berechne die MD5 in der Inhaltszeichenkette und vergleiche sie mit der MD5 der lokalen Datei. So etwas wieboto get md5 s3 Datei

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 

Dieser Ansatz ist verschwenderisch, da es die Bandbreitennutzung verdoppelt. Ich versuchte

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

aber beide zurück keine.

Gibt es eine andere Möglichkeit, MD5 zu erreichen, ohne das Ganze herunterzuladen?

Antwort

13

ja
Verwendung bucket.get_key('file_name').etag[1 :-1]
diese Weise Schlüssel des MD5 erhalten, ohne seinen Inhalt herunterzuladen.

+12

Beachten Sie, dass es nur für Dateien korrekt ist, die in einem einzigen Teil hochgeladen wurden. Wenn Sie Multipart-Download verwenden, ist das Etag nicht das MD5 und Sie müssen die Datei herunterladen, um den Hash zu berechnen – Beka

+0

Danke @Beka wusste nicht, dass – NoamG

+2

Ich stimme @Beka nicht, können Sie die MD5, die Amazon ohne verwenden Herunterladen der Datei Weitere Informationen finden Sie unter dieser Frage: http://stackoverflow.com/questions/6591047/etag-definition-changed-in-amazon-s3/28877788#28877788 – Spedge

2

Mit Boto3 verwende ich head_object, um das ETag abzurufen.

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

Das Etag ist nicht immer der MD5-Hash eines Objekts. – algal

Verwandte Themen