1282 字
约 4 分钟
1
可靠下载:断点续传 + `.part` 临时文件 + 原子改名
可靠下载:断点续传 + .part 临时文件 + 原子改名
目标:学会一套通用、可迁移、防坑的可靠 IO 设计。看似很普通,其实藏着三个容易被忽略的细节。以后做任何"可能中断 + 不希望中间态被当成品"的任务(大文件下载/上传分片/缓存/批处理),都能直接借鉴。
一、先给判断:是"断点续传"吗?是,但不只
直接说——它就是断点续传那一家族的,不是新东西。但它其实是三件套,很多人只记住了"续传",却漏了两个更值钱的细节:
| 机制 | 是什么 | 解决什么问题 |
|---|---|---|
① .part 临时文件 |
先下载到 xxx.part,下完才改成 xxx.mp4 |
防止"下到一半断了"时目录里留个残缺的假视频骗人 |
| ② 断点续传(Range 头) | 重下时读 .part 已有大小,发 Range: bytes=<已有大小>-,从断点继续 |
断网后不用从头下 |
| ③ 原子改名 | 完成的一瞬间 try_rename(part, 正式名) |
保证**"要么没有,要么完整"**,不出现半截文件被当成品 |
[!tip] ① 和 ③ 才是精华。续传 ② 大家都会想到;①③ 却最容易漏,却最能防坑。
二、为什么 ①(.part 临时文件)值得学
没有 .part 的情况:
下到 50% 断开 → 目录里出现一个残缺的 xxx.mp4。
- 你双击它 → 打不开
- 脚本判断"文件在否" → 在 → 结果是个坏的
有了 .part:
断时目录里只有 xxx.mp4.part,谁都知道这是"未完待续",不会误当成品。
[!important] 结尾那个看似多余的
.part后缀,其实是在给文件贴了张 "未完成"标签。别小看这一个后缀。
三、为什么 ③(原子改名)最值钱
最后一步是一瞬间把 .part 改名为正式名。在支持的平台上,rename 是原子操作。
效果:
任何时刻你去看目录,只会看到两种之一:
· 旧的完整文件 xxx.mp4(还没开始新的)
· 还没改名的 xxx.part(新的还没下完)
绝不会看到"一个更新到一半的 xxx.mp4"
[!important] 这就是"要么没有,要么完整"的语义。它把"危险的、多步骤的下载"包装成一个"看起来一瞬间完成"的原子操作,外部永远看不到中间态。
四、为什么 ②(Range 续传)省流量
断点续传的实现细节:
第一步:看 .part 已经有多少字节 → 记为 resume_len
第二步:发请求时带请求头 Range: bytes=<resume_len>-
第三步:服务器从 resume_len 开始继续发剩下的字节
「若服务器不支持 Range → 丢弃残留,从头重新下」
这样一次断网回来,只把剩下的部分下完,不用整文件重下。
五、在哪用得上(不只是视频下载)
| 你的场景 | 套用这套 |
|---|---|
| 上传大文件 | 先传 xx.part,传完改名 xx → 对方永远拿不到半个文件 |
| 写大日志 / 缓存文件 | 写临时文件再原子改名 → 崩溃时旧文件还是好的 |
| 数据库导入 / 批处理 | 处理结果先写 .tmp,成功后再改名 → 失败自动丢弃残留 |
| 更新 / 安装包 | 下到 .part,校验完再替换 → 不会留下损坏的程序 |
通用规律:凡是"可能中断 + 不希望中间态当成品"的任务,都该:先写临时文件 → 完成才改名。
六、核心金句(比"断点续传"四个字值钱)
真正的价值不在"续传",而在于其中两个更朴素的技巧:
- 临时文件:给未完成的东西贴"未完"标签,防半截文件骗人
- 原子改名:用"临时文件 + 改名"把危险的多步骤包成原子操作,保证"要么全成,要么没有"
这就是可靠编程里的核心思维。用好了,你在任何长任务里都不会留下半成品污染状态。
七、在 yt-dlp 里对应哪里(供回溯)
- 临时文件名:
yt_dlp/downloader/common.py的temp_name()/undo_temp_name()/ytdl_filename() - 续传逻辑:
yt_dlp/downloader/http.py(读.part大小 → 发Range头) - 原子改名:
try_rename(part, 正式名)在下载完成时调用 - 学习库 → [[Downloader-Subsystem]]
八、一句话带走
别只记着"断点续传"——学会这三件套:先写
.part(标记未完成)→ 用 Range 从断点续传 → 完成瞬间原子改名。它给你的不是新功能,而是**"要么没有、要么完整"的可靠结果**,做任何可中断的长任务都用得上。
可靠下载:断点续传 + `.part` 临时文件 + 原子改名
http://www.clxhxhhr.top/posts/528/ 评论
0 条
还没有评论,先写一条吧。