提示

返回博客列表

大文件下载总中断?聊聊断点续传与并发分片下载的工程实现

大文件下载总中断?聊聊断点续传与并发分片下载的工程实现

前面聊 m3u8 合并、聊 CDN 就近接入,都是在"怎么拿到地址、怎么快"。本文往前一步:地址有了、网也不差,可一个几 GB 的文件下到 90% 断了怎么办?工程上靠两样东西——断点续传并发分片

目录

一、HTTP Range:下载的"书签"

关键在于请求头 Range

Range: bytes=0-1023

服务端若支持,返回 206 Partial Content 并带上 Content-Range: bytes 0-1023/5000,只给这一段。判断是否支持,看响应里有没有 Accept-Ranges: bytes

二、断点续传:从断的地方继续

思路极简:

  1. 下载前记录"已落盘字节数 offset";
  2. 重发请求时带 Range: bytes=offset-
  3. 追加模式写入文件,而不是覆盖。
def resume_download(url, path):
    offset = os.path.getsize(path) if os.path.exists(path) else 0
    headers = {'Range': f'bytes={offset}-'}
    with requests.get(url, headers=headers, stream=True) as r:
        mode = 'ab' if offset else 'wb'   # 有进度就追加
        with open(path, mode) as f:
            for chunk in r.iter_content(8192):
                f.write(chunk)

断网、程序崩溃都不怕——重启后 offset 还是那个值,从头续上。

三、并发分片:把文件切成几段一起下

单连接受限于一条 TCP 的吞吐,把文件按大小切成 N 段,每段独立一个 Range 线程/协程并行下载,最后按顺序拼起来:

import asyncio, aiohttp

async def fetch_range(session, url, start, end, path):
    headers = {'Range': f'bytes={start}-{end}'}
    async with session.get(url, headers=headers) as r:
        data = await r.read()
        with open(path, 'r+b') as f:
            f.seek(start)
            f.write(data)          # 各段按偏移写回原位

async def parallel(url, size, parts=8):
    step = size // parts
    async with aiohttp.ClientSession() as s:
        tasks = []
        for i in range(parts):
            st = i * step
            ed = size - 1 if i == parts-1 else (i+1)*step - 1
            tasks.append(fetch_range(s, url, st, ed, 'out.bin'))
        await asyncio.gather(*tasks)

注意:文件要先以 r+b 预分配大小(f.truncate(size)),各段才能 seek 到正确偏移写入。

四、合并与校验

  • 分片落同一文件:如上,seek 回写,天然有序,无需再拼接。
  • 分片落多个临时文件:则严格按段序号顺序 cat;顺序错了就是乱码。
  • 校验:下完比对 Content-Length 或算 md5/sha256,防止某段静默损坏。

这种"先分片下载、再合并成完整文件"的思路,和 用 ffmpeg 把 m3u8 合并成 mp4 是同一类工程问题,只是对象从 TS 片段变成了字节区间。

五、常见坑

现象 原因 解决
返回 200 而非 206 服务端不支持 Range 只能单连接,放弃分片
合并后画面错位 段顺序写反 / 偏移算错 严格按 start 偏移写回
续传从头开始 用了覆盖模式 wb 改用追加 ab
速度没提升 单 IP 被限速 / 线程过多 控制并发数,参考 CDN 就近接入 的思路选近节点

断点续传 + 并发分片,是把"大文件下载"从"听天由命"变成"可控工程"的两块基石。

想亲手试试?用 VidDown 一键解析下载

粘贴视频链接即可解析,多平台支持、网页端即用;下载桌面客户端解锁海外平台本地解析,开通会员更享不限次下载。

顶部