下载大文件断点续传:curl -C / wget / aria2c 三种用法

起因

跨大洋下载 50 GB 数据集,到一半网断了。重新跑 = 重新下完整 50GB。
HTTP 标准里有 Range header(断点续传),客户端工具不全自动用。

curl:-C - 自动续传

curl -C - -O https://example.com/big.tar.gz
# -C - 让 curl 检测本地文件大小 + Range header 续传
# -O 用 server 提供的文件名保存

如果服务端不支持 Range:

curl: (33) HTTP server doesn't seem to support byte ranges. Cannot resume.

绝大多数现代 HTTP server / CDN 都支持。

加速 / 重试

curl -C - -O \
  --retry 5 \
  --retry-delay 10 \
  --retry-max-time 3600 \
  --limit-rate 10M \
  -L \
  https://example.com/big.tar.gz
  • --retry 5:网络错误自动重试 5 次
  • --retry-delay 10:间 10 秒
  • --retry-max-time 3600:1 小时内重试
  • --limit-rate 10M:限速 10MB/s(晚上无人时占满带宽,白天礼貌点)
  • -L:跟 redirect

校验

curl -O https://example.com/big.tar.gz
curl -O https://example.com/big.tar.gz.sha256
sha256sum -c big.tar.gz.sha256

下完一定要校验,网络可能让文件损坏。

wget:默认更友好

wget -c https://example.com/big.tar.gz
# -c 续传

加重试 / 限速:

wget -c \
  --tries=10 \
  --retry-connrefused \
  --waitretry=30 \
  --limit-rate=10m \
  --user-agent='Mozilla/5.0' \
  https://example.com/big.tar.gz

镜像整个目录:

wget -r -np -nH --cut-dirs=2 -R 'index.html*' \
  https://example.com/files/2024/
  • -r 递归
  • -np 不向上跳目录
  • -nH 不创建 host name 目录
  • --cut-dirs=2 砍掉前 2 级路径
  • -R 'index.html*' 排除目录列表 HTML

aria2c:多连接 + magnet + 元数据 vacuum

sudo apt install aria2
brew install aria2

aria2c -x 16 -s 16 https://example.com/big.tar.gz
# -x 16: 同一服务器最多 16 个连接
# -s 16: 同一文件用 16 个 segment 并行下

如果服务端支持 Range,多个 TCP 连接并行下不同字节范围,
吃满带宽(单 TCP 流由于 congestion control 经常吃不满)。
速度通常 3-5x 单连接。

更激进:

aria2c -x 16 -s 16 -j 4 -k 1M --file-allocation=falloc \
  --max-tries=10 --retry-wait=30 \
  https://example.com/big.tar.gz
  • -j 4: 同时下 4 个文件
  • -k 1M: 每 segment 至少 1MB
  • --file-allocation=falloc: ext4/xfs 上预分配文件(防碎片)

aria2c 支持的协议

# HTTPS
aria2c https://...

# FTP
aria2c ftp://user:pass@host/path

# BitTorrent
aria2c some.torrent

# Magnet link
aria2c 'magnet:?xt=urn:btih:...'

# metalink (含多个 mirror)
aria2c file.metalink

下大文件 magnet 时 aria2c 远比传统 BT 客户端轻量。

多 mirror

aria2c \
  https://us.mirror.example.com/big.tar.gz \
  https://eu.mirror.example.com/big.tar.gz \
  https://asia.mirror.example.com/big.tar.gz

3 个 mirror 同时下,每个用不同 segment。
带宽利用最大化。

续传

aria2 默认自动续传:

aria2c https://example.com/big.tar.gz
# 中断 → 再跑同命令,从断点继续

断点信息在 .aria2 控制文件里。

rsync:对增量传输最优

rsync -avz --progress --partial \
  user@server:/path/to/big.tar.gz \
  ./big.tar.gz
  • --partial:保留部分传输的文件供下次续传
  • --progress:显示进度条
  • rsync 还能传整个目录树 + 只传差异,比 scp 强 10x

更激进的限速 / 加密:

rsync -avz --bwlimit=10000 \
  -e 'ssh -c [email protected]' \
  src/ dst:/path/

--bwlimit=10000 = 10 MB/s。aes128-gcm 加密快(用现代 CPU 的 AES-NI),
比默认 ChaCha20 快 2-3 倍。

边下边校验:sha256 + tee

curl -L https://example.com/big.tar.gz | tee big.tar.gz | sha256sum -
# 边下载 + 边写文件 + 边算 hash
# 输出 hash 后对比 expected

适合一次性下 + 校验场景。

限速 + 后台 + 续传完整组合

# 启动一个后台下载
nohup aria2c -x 8 -s 8 --max-overall-download-limit=20M \
  --enable-rpc=true --rpc-listen-all=true --rpc-secret=mysecret \
  -d ~/Downloads -o big.tar.gz \
  https://example.com/big.tar.gz \
  > ~/Downloads/aria2.log 2>&1 &

# 通过 RPC 控制(暂停 / 看进度)
curl -s -d '{"jsonrpc":"2.0","method":"aria2.tellActive","id":"x","params":["token:mysecret"]}' \
  http://localhost:6800/jsonrpc | jq

aria2 RPC 让你用 web UI(aria2-webui)控制。Synology / OpenMediaVault
等 NAS 都有 aria2 GUI 包。

服务端:让你的文件支持 Range

nginx:

location /downloads/ {
    alias /var/www/downloads/;
    # 默认 nginx 静态文件就支持 Range,不需要配
}

应用程序自己 stream 大文件时(如 Django/FastAPI/Flask),要手动处理
Range header。或者直接让 nginx 服务静态文件(最快)。

反过来:让别人能续传我的下载

# FastAPI 例
from fastapi import FastAPI, Request, Response
from fastapi.responses import StreamingResponse, FileResponse
import os

@app.get('/download/{filename}')
def download(filename: str, request: Request):
    path = f'/var/files/{filename}'
    # FileResponse 自动处理 Range
    return FileResponse(path, filename=filename)

FileResponse / nginx X-Sendfile 都支持 Range。
自己写 stream generator 要:

  • Range: bytes=100-200 header
  • 返回 206 Partial Content + Content-Range

效果

跨太平洋下 50GB(实测):

工具 时间 带宽利用 注意
curl 6h 25% 单 TCP
wget -c 6h 25% 同上
aria2c -x 8 1.5h 95% 8 并行
aria2c + 3 mirror 45min 100% 3 mirror × 8 段
rsync 7h 22% SSH 加密开销

中断续传都 OK,但 aria2c 显著快。

踩过的坑

  1. 服务端不支持 Range → curl -C - 直接报错。
    测试:curl -I -H "Range: bytes=0-100" https://...
    返回 206 Partial Content = 支持。

  2. proxy / CDN 不传 Range → 一些反代默认 buffer,吞 Range header。
    nginx 加 proxy_set_header Range $http_range;

  3. aria2c segment 上限:每个 segment 一个 TCP 连接,过多反而
    慢(拥塞 + 服务端 ratelimit)。8-16 是甜点。

  4. 文件名含特殊字符 / 编码:URL encode 不完整时下错文件。
    curl -o "myname.tar.gz" -L url 显式指定本地名。

  5. 磁盘满 silent fail:下载到 99% 磁盘满 → 文件损坏。
    df -h 提前确认空间。

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。