直接贴示例代码:
1. 服务端代码:
from rest_framework.response import Response
from django.http.response import StreamingHttpResponse
def file_iterator(file_name, chunk_size=512):
with open(file_name, 'rb') as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break
@api_view(['GET'])
@permission_classes((TokenHasReadWriteScope, ))
def download_view(request, format=None):
file_name= request.query_params.get('file_name', None)
if not file_name:
return Response(None, status=status.HTTP_400_BAD_REQUEST)
found = [p for p in glob.glob('{0}/*'.format(file_dir)) if p.endswith('.rpm')]
file_path = YOUR_DIR + file_name
response = StreamingHttpResponse(file_iterator(file_path)) # 切片
response['Content-Type'] = 'application/octet-stream'
response['File-Name'] = os.path.basename(file_path)
try:
with open('{}.md5'.format(file_path), 'r') as f: # MD5值校验
md5sum = f.read().strip()
except FileNotFoundError:
md5sum = 'no file'
response['Md5sum'] = md5sum
return response
2. 客户端代码:
def hash_file(file, buf_size=65536):
md5 = hashlib.md5()
if os.path.exists(file):
with open(file, 'rb') as f:
while True:
data = f.read(buf_size)
if not data:
break
md5.update(data)
return md5.hexdigest()
def download_from_agent(file_name):
res = requests.get(STATION_DOWNLOAD_URI + '?file_name={0}'.format(file_name)
if res.status_code != 200:
raise IOError('Download faild.')
else:
file_name = res.headers['File-Name']
file_path = '{0}/{3}'.format(YOUR_DIR, file_name)
if not os.path.exists(YOUR_DIR):
os.mkdir(YOUR_DIR)
with open(file_path, 'wb+') as f:
for chunk in res.iter_content(chunk_size=1024): # 切片
if chunk:
f.write(chunk)
if res.headers['Md5sum'] != hash_file(file_path):
raise IOError('Broken file.')
return file_path