网络编程
位置:首页>> 网络编程>> Python编程>> Python 工具类实现大文件断点续传功能详解

Python 工具类实现大文件断点续传功能详解

作者:剑客阿良_ALiang  发布时间:2022-11-17 05:41:29 

标签:Python,文件下载,断点续传

依赖

os、sys、requests

工具代码

废话不多说,上代码。


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 23 13:54:39 2021
@author: huyi
"""

import os
import sys

import requests

def download(url, file_path):
   # 重试计数
   count = 0
   # 第一次请求是为了得到文件总大小
   r1 = requests.get(url, stream=True, verify=False)
   total_size = int(r1.headers['Content-Length'])

# 判断本地文件是否存在,存在则读取文件数据大小
   if os.path.exists(file_path):
       temp_size = os.path.getsize(file_path)  # 本地已经下载的文件大小
   else:
       temp_size = 0

# 对比一下,是不是还没下完
   print(temp_size)
   print(total_size)

# 开始下载
   while count < 10:
       if count != 0:
           temp_size = os.path.getsize(file_path)
       # 文件大小一致,跳出循环
       if temp_size >= total_size:
           break
       count += 1
       print(
           "第[{}]次下载文件,已经下载数据大小:[{}],应下载数据大小:[{}]".format(
               count, temp_size, total_size))
       # 重新请求网址,加入新的请求头的
       # 核心部分,这个是请求下载时,从本地文件已经下载过的后面下载
       headers = {"Range": f"bytes={temp_size}-{total_size}"}
       # r = requests.get(url, stream=True, verify=False)
       r = requests.get(url, stream=True, verify=False, headers=headers)

# "ab"表示追加形式写入文件
       with open(file_path, "ab") as f:
           if count != 1:
               f.seek(temp_size)
           for chunk in r.iter_content(chunk_size=1024 * 64):
               if chunk:
                   temp_size += len(chunk)
                   f.write(chunk)
                   f.flush()
                   ###这是下载实现进度显示####
                   done = int(50 * temp_size / total_size)
                   sys.stdout.write("\r[%s%s] %d%%" % (
                       '█' * done, ' ' * (50 - done), 100 * temp_size / total_size))
                   sys.stdout.flush()
       print("\n")

return file_path

代码说明:

1、重试次数可以自己修改,按照需求来,我这边是10次。

2、增加了进度条的打印,别问,好看就完了。

验证一下,我们准备个文件下载服务。上文件服务代码。代码对flask、gevent有依赖。


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 23 19:53:18 2021
@author: huyi
"""

from flask import Flask, request, make_response, send_from_directory
from gevent.pywsgi import WSGIServer
from gevent import monkey

# 将python标准的io方法,都替换成gevent中的同名方法,遇到io阻塞gevent自动进行协程切换
monkey.patch_all()
app = Flask(__name__)

@app.route("/download", methods=['GET'])
def download_file():
   get_data = request.args.to_dict()
   file_path = get_data.get('fileName')

response = make_response(
       send_from_directory('/Users/huyi/Movies/Videos',file_path,as_attachment=True))
   response.headers["Content-Disposition"] = "attachment; filename={}".format(
       file_path.encode().decode('latin-1'))
   return response

if __name__ == '__main__':
   WSGIServer(('0.0.0.0', 8080), app).serve_forever()

启动文件下载服务,测试下载代码


download('http://localhost:8080/download?fileName=test.mp4', '/Users/huyi/Downloads/test.mp4')

首先我们下载一部分,然后关闭,模拟下载一半的情况。

Python 工具类实现大文件断点续传功能详解

重新执行一下,把剩下的执行

Python 工具类实现大文件断点续传功能详解

OK,验证通过。

来源:https://huyi-aliang.blog.csdn.net/article/details/120926552

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com