マルチパートアップロードを使用して、数百のファイルを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
このアプローチは、帯域幅の使用量が2倍になるため、無駄です。私は試した
bucket.get_key('file_name').md5
bucket.get_key('file_name').base64md5
ただし、どちらもNoneを返します。
すべてをダウンロードせずにmd5を実現する他の方法はありますか?
はい
use bucket.get_key('file_name').etag[1 :-1]
この方法で、キーの内容をダウンロードせずにキーのMD5を取得します。
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
2016年以降、追加のオブジェクトを取得せずにこれを行う最善の方法は、PutObjectリクエスト中に--content-md5
引数を提示することです。 AWSは、提供されたMD5が計算されたMD5と一致することを確認します。これは、マルチパートアップロードおよび5GBを超えるオブジェクトでも機能します。
ナレッジセンターからの呼び出し例:
aws s3api put-object --bucket awsexamplebucket --key awsexampleobject.txt --body awsexampleobjectpath --content-md5 examplemd5value1234567== --metadata md5checksum=examplemd5value1234567==
https://aws.Amazon.com/premiumsupport/knowledge-center/data-integrity-s3/