当前位置:首页 > 文章列表 > 文章 > linux > Linux curl分段下载大文件并校验完整性的实现

Linux curl分段下载大文件并校验完整性的实现

来源:17golang原创 2026-09-20 16:00:00 0浏览 收藏

Linux 上处理几个 GB 甚至更大的文件时,可以把文件按字节区间拆成多个片段,用 curl --range 分别保存,再按顺序合并。真正决定结果是否可靠的不是“命令执行完了”,而是每段都返回了预期范围、合并后的字节数正确,并且最终 SHA-256 摘要与发布方提供的值一致。

官方文档:https://curl.se/docs/manpage.html

推荐把“分段下载、片段检查、顺序合并、摘要校验”做成一个有失败出口的脚本。只要服务端忽略 Range 返回 200,就立即停止,不能把完整响应误当成某一段。

先确认 curl 分段下载的前提

--range start-end 表示请求指定的字节范围,例如 0-1048575 是前 1 MiB。curl 官方手册也提醒,部分 HTTP 服务端不支持 Range,收到请求后会直接返回完整文件;这时响应通常是 200,而不是 206 Partial Content。--continue-at 是从已有文件偏移处续传,和 --range 不能在一次传输中混用,二者不要混成一个恢复逻辑。

因此,脚本至少需要三个已知量:下载地址、文件总长度 total、分片大小 chunk。总长度应来自可信的发布清单或已确认的响应头,不要用一次失败下载得到的本地大小反推。

curl按字节起止位置拆分大文件的静态结构说明图
图1:curl Range 字节边界说明图,展示连续片段如何覆盖完整文件;这是静态结构图,不是运行截图。

固定边界并检查每个片段

下面的脚本采用顺序下载,便于排查。每一段的结束位置是 start + chunk - 1,最后一段再限制为 total - 1。保存片段前检查 HTTP 状态,保存后检查实际字节数,两个条件任何一个不满足都退出。

#!/usr/bin/env bash
# 这段脚本按固定字节区间下载,并拒绝服务端忽略 Range 的响应。
set -euo pipefail

url="https://mirror.example.org/releases/demo.tar.zst"
total=838860800                 # 这里填写已确认的总字节数,不用本地文件大小猜测
chunk=$((64 * 1024 * 1024))     # 每段 64 MiB,按网络和磁盘情况调整
work="demo.parts"
output="demo.tar.zst"
mkdir -p "$work"
: > "$work/parts.list"          # 清空旧清单,避免混入上一次失败的片段

for ((start=0; start= total )) && end=$((total - 1))
  part="$work/part-${start}-${end}"
  header="$part.headers"

  # --fail 遇到HTTP错误退出;--range只请求当前闭区间。
  curl --fail --show-error --location \
    --range "${start}-${end}" \
    --dump-header "$header" \
    --output "$part" "$url"

  # Range成功应得到206;否则说明服务端可能返回了整文件,立即停止。
  status=$(awk '/^HTTP\// { code=$2 } END { print code }' "$header")
  [[ "$status" == "206" ]] || { echo "Range未生效: HTTP $status" >&2; exit 1; }

  expected=$((end - start + 1))
  actual=$(wc -c &2; exit 1; }
  printf '%s\n' "$part" >> "$work/parts.list"
done

按清单合并并做两层确认

下载成功不代表最终文件正确。合并时只读取当前清单中的片段,并用追加模式保持顺序;随后先比较字节数,再比较摘要。字节数能较快发现漏段或重复段,摘要则能发现内容被替换、截断但长度碰巧相同等问题。

# 只按下载阶段写入的顺序合并,避免通配符排序改变片段次序。
rm -f "$output"
while IFS= read -r part; do
  cat "$part" >> "$output"
done &2
  exit 1
}

# checksum.txt 的格式必须是“摘要 空格 文件名”,供 sha256sum -c 读取。
sha256sum "$output" > "$work/local.sha256"
sha256sum -c checksum.txt
echo "下载、合并和SHA-256校验完成: $output"

如果发布方只给出一串摘要,也可以先生成本地结果,再用 sha256sum 的输出比较;不要把摘要写进未经确认的 checksum.txt 后再对自己生成的文件做“自证”。摘要文件应来自发布方、镜像目录或签名清单。

Linux分片合并后先比较字节数再验证SHA-256的结构说明图
图2:片段清单、顺序合并、字节数检查和 SHA-256 校验的关系图;这是静态结构图,不是运行截图。

失败时按证据定位,不要盲目重试

看到 200 时,先确认服务端是否支持 Range、重定向后的地址是否改变,以及代理是否移除了 Range 请求。看到片段长度不符时,检查是否遇到压缩传输、服务端动态内容或边界计算错误;不要直接把响应追加到最终文件。若只有某一段失败,可以删除该段及其响应头后重新下载,但要再次检查状态、长度和清单顺序。

如果最终摘要失败,优先对比片段清单和总字节数,再逐段重新计算摘要,定位是漏段、重复段还是源文件本身已经更新。下载过程中源文件发生变化时,即使每段都是 206,拼出来的文件也可能没有任何一个稳定版本的摘要;此时应固定版本 URL 或使用带版本标识的发布清单。

速查清单与常见疑问

  • Range 生效:每段响应为 206,且实际字节数等于 end-start+1
  • 边界无重叠:第一段从 0 开始,最后一段结束于 total-1
  • 合并可复现:使用固定清单,不依赖目录通配符顺序。
  • 校验可信:摘要来自发布方,不能用本地刚生成的摘要代替。

curl 不支持 Range 怎么办?这通常不是 curl 参数写错,而是服务端没有启用字节范围,或中间代理改变了响应。改用普通下载或更换支持 Range 的镜像,并保留完整性校验。

为什么不直接用 -C ---continue-at适合单文件断点续传;需要并行、重试单段或保存每段证据时,显式的 Range 清单更容易控制边界和恢复。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go t.Cleanup登记资源释放动作的测试结构Go t.Cleanup登记资源释放动作的测试结构
上一篇
Go t.Cleanup登记资源释放动作的测试结构
Go embed路径使用反斜杠导致跨平台读取失败的排查
下一篇
Go embed路径使用反斜杠导致跨平台读取失败的排查
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    136次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    202次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    147次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    127次使用
  • CMMLU中文大模型评估基准:功能、使用教程与应用场景解析
    CMMLU
    深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
    115次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码