2014-10-17 3 views
5

멀티 파트 uplaod를 사용하여 수백 개의 파일을 내 S3 버킷에 업로드하는 유스 케이스가 있습니다. 각 업로드 후에 업로드 된 파일이 손상되지 않았는지 확인해야합니다 (기본적으로 데이터 무결성 검사). 현재, 파일을 업로드 한 후, 파일을 다시 다운로드하고 내용 문자열에서 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에 동의하지 않고, Amazon이 사용하지 않는 md5를 알아낼 수 있습니다. 파일을 다운로드합니다. 자세한 내용은 다음 질문을 참조하십시오. 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

etag는 항상 객체의 md5 해시가 아닙니다. – algal

관련 문제