服务器之家

服务器之家 > 正文

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

时间:2022-02-20 00:08     来源/作者:剑客阿良_ALiang

依赖

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,验证通过。

 

总结

断点续传的这部分代码,你可以好好理解一下原理,其实不复杂。还是不明白可以私信我。

如果本文对你有帮助,请点个赞支持一下吧。

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

到此这篇关于Python 工具类实现大文件断点续传功能详解的文章就介绍到这了,更多相关Python 文件下载内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://huyi-aliang.blog.csdn.net/article/details/120926552

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
2022年最旺的微信头像大全 微信头像2022年最新版图片
2022年最旺的微信头像大全 微信头像2022年最新版图片 2022-01-10
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
返回顶部