我想检查从s3下载的文件是否下载良好
所以我决定使用etag值
上传到s3 bucket的对象的etag值与通过python md5找到的值不同
顺便说一下,上传到s3 bucket的对象的etag值和我通过python md5找到的值是不同的
以下是我使用的代码:
#!/usr/bin/env python3.6
import os
import sys
from hashlib import md5
from argparse import ArgumentParser
parser = ArgumentParser(description='Compare an S3 etag to a local file')
parser.add_argument('inputfile', help='The local file')
parser.add_argument('etag', help='The etag from s3')
args = parser.parse_args()
def factor_of_1MB(filesize, num_parts):
x = filesize / int(num_parts)
y = x % 1048576
return int(x + 1048576 - y)
def calc_etag(inputfile, partsize):
md5_digests = []
with open(inputfile, 'rb') as f:
for chunk in iter(lambda: f.read(partsize), b''):
md5_digests.append(md5(chunk).digest())
return md5(b''.join(md5_digests)).hexdigest() + '-' + str(len(md5_digests))
def possible_partsizes(filesize, num_parts):
return lambda partsize: partsize < filesize and (float(filesize) / float(partsize)) <= num_parts
def main():
filesize = os.path.getsize(args.inputfile)
num_parts = int(args.etag.split('-')[1])
partsizes = [ ## Default Partsizes Map
8388608, # aws_cli/boto3
15728640, # s3cmd
factor_of_1MB(filesize, num_parts) # Used by many clients to upload large files
]
for partsize in filter(possible_partsizes(filesize, num_parts), partsizes):
if args.etag == calc_etag(args.inputfile, partsize):
print('Local file matches')
sys.exit(0)
print('Couldn\'t validate etag')
sys.exit(1)
if __name__ == "__main__":
main()
python3 <file> <aws s3 etag value>
它表示不一致,但与执行以下代码后显示的值相匹配
import hashlib
def calculate_s3_etag(file_path, chunk_size=16 * 1024 * 1024):
md5s = []
with open(file_path, 'rb') as fp:
while True:
data = fp.read(chunk_size)
if not data:
break
md5s.append(hashlib.md5(data))
if len(md5s) < 1:
return '"{}"'.format(hashlib.md5().hexdigest())
if len(md5s) == 1:
return '"{}"'.format(md5s[0].hexdigest())
digests = b''.join(m.digest() for m in md5s)
digests_md5 = hashlib.md5(digests)
return '"{}-{}"'.format(digests_md5.hexdigest(), len(md5s))
if __name__ == "__main__":
print(calculate_s3_etag('./<filename>'))
在这里,我将块大小更改为16。结果表明,运行此代码得到的etag值与我在第一个代码中输入的etag值相匹配
请帮助我如何获取aws etag值
测试是用一个150mb的wmv文件完成的
此外,我测试了57kb的csv文件,它运行良好
目前没有回答
相关问题 更多 >
编程相关推荐