Verwenden Sie Python-Codierung, um den Breakpoint-Download von Dateien zu implementieren
import os
import json
import hashlib
import logging
import requests
import traceback
from contextlib import closing
logger = logging.getLogger()
def download_file(url, save_file_path, new_file_name):
"""
下载文件
:param url: 目标文件 url
:param save_file_path: 本地保存下载文件的路径
:param new_file_name: 文件名称
:return: (status, md5, msgs)
:rtype: status INT, 0: 下载成功, -1:下载失败
:rtype: md5 STRING, 下载成功返回 md5 值,否则返回 None
:rtype: msgs STRING, 对下载结果的描述信息
"""
logger.info(f"Start to download file, url: {
url}")
try:
os.mkdir(save_file_path)
except FileExistsError:
pass
except FileNotFoundError:
os.makedirs(save_file_path)
file_content = bytearray()
try:
with closing(requests.get(url=url, stream=True)) as res:
if res.status_code != 200:
return -1, None, res.text
try:
json_res = json.loads(res.content)
message = f"Download file failed, code: {
json_res.get('code')}, msg: {
json_res.get('msg')}"
logger.error(message)
return -1, None, message
except Exception:
with open(save_file_path + new_file_name, 'wb') as fd:
for chunk in res.iter_content(chunk_size=1024):
if chunk:
fd.write(chunk)
file_content.extend(chunk)
hash_obj = hashlib.md5()
hash_obj.update(file_content)
logger.info(f"End to download file, url: {
url}, filename: {
new_file_name}")
return 0, hash_obj.hexdigest(), "Success"
except Exception as e:
logger.error(traceback.format_exc())
return -1, None, str(e)
def breakpoint_download_file(file_url, file_dir, new_file_name):
"""断点续传下载文件"""
logger.info(f"Start breakpoint download file, file_url: {
file_url}")
try:
os.mkdir(file_dir)
except FileExistsError:
pass
except FileNotFoundError:
os.makedirs(file_dir)
# 设置 headers,检查文件下载进度
file_path = file_dir + new_file_name
if os.path.exists(file_path):
start_byte = os.path.getsize(file_path)
else:
start_byte = 0
headers = {
'Range': f'bytes={
start_byte}-'}
# 发送 GET 请求
try:
with closing(requests.get(url=file_url, stream=True, headers=headers)) as res:
# 206表示该服务器已经成功处理了部分 GET 请求
if res.status_code not in [200, 206]:
return -1, None, res.text
# 获取总字节数,计算出剩余未下载的字节数
total_size = int(res.headers.get('content-length', 0))
remaining_bytes = total_size - start_byte
# 写入文件
with open(file_path, 'ab') as f:
for chunk in res.iter_content(chunk_size=1024):
# 如果已经下载完成,退出循环
if remaining_bytes <= 0:
break
# 计算本次需要写入的字节数
bytes_to_write = len(chunk)
if bytes_to_write > remaining_bytes:
bytes_to_write = remaining_bytes
# 写入文件并更新记录
f.write(chunk[:bytes_to_write])
remaining_bytes -= bytes_to_write
# 以二进制只读方式打开文件并计算 MD5 校验和
# 以二进制只读方式打开文件并计算 MD5 校验和
with open(file_path, 'rb') as f:
md5_hash = hashlib.md5()
chunk = f.read(8192)
while chunk:
md5_hash.update(chunk)
chunk = f.read(8192)
logger.info(f"End to download file, url: {
file_url}, filepath: {
file_path}, "
f"filesize: {
os.path.getsize(file_path)}, md5: {
md5_hash.hexdigest()}")
return 0, md5_hash.hexdigest(), "Success"
except Exception as e:
logger.error(traceback.format_exc())
return -1, None, str(e)
# if __name__ == '__main__':
# breakpoint_download_file(
# file_url="https://yos.yingzi.com/prod-bucket-iot/prod-iot-storage/1082233093836513280/MW301_ver2.2.30.ota",
# file_dir='./', new_file_name="MW301_MW301_2.2.30.ota")