技术笔记

系统调优 · 工具使用 · 踩坑记录

← 返回首页
工具

下载工具:aria2 与自制的 pget

单线程下载大文件时,你可能只用到了一半带宽。

2026-11 · 约 6 分钟

为什么需要多线程下载

单条连接的速度受两个因素限制:窗口大小和往返延迟。 延迟越高(比如跨国、跨运营商),单连接能跑满的带宽就越低。

开多个连接就能绕开这个限制——每个连接各拉一段,合起来吃满带宽。

实测一个 200MB 文件:

方式速度
单线程 curl24.9 MB/s
aria2 -x16 -s1636.6 MB/s
pget 8 线程40.0 MB/s
但分片只在「服务器单连接被限速」时才有意义。 有些站单流本来就不限速(比如 GitHub),分片反而更慢—— 实测 39MB 文件:单流 15 MB/s,8 线程只有 9.8 MB/s。

一、aria2:功能最全

macOS 不自带,Homebrew 一条命令:

brew install aria2

常用命令

# 普通下载(16 连接)
aria2c -x16 -s16 -k1M https://example.com/file.iso

# 断点续传(断了重跑同一条命令即可)
aria2c -c -x16 -s16 https://example.com/file.iso

# 指定目录和文件名
aria2c -x16 -s16 -d ~/Downloads -o ubuntu.iso https://example.com/ubuntu.iso

# 限速,别把带宽占满
aria2c -x8 --max-download-limit=20M https://example.com/file.iso

参数说明:

参数含义
-x单服务器最多连接数
-s文件切成几段
-k每段最小大小(太小反而增加开销)
-c断点续传

小文件把 -x / -s 降到 4~8 更合适, 16 连接对 10MB 的文件纯属浪费。

二、pget:不装任何东西的多线程下载

不想装 aria2 的话,macOS 自带的 curl 就够了。原理是用 HTTP 的 Range 头把文件切成几段,并发下载后拼接。

#!/bin/sh
# pget —— 多线程分片下载(纯 curl 实现)
# 用法: pget <URL> [线程数] [输出文件]

URL="${1:-}"; N="${2:-8}"; OUT="${3:-}"
[ -z "$URL" ] && { echo "用法: pget  [线程数] [输出]"; exit 1; }
[ -z "$OUT" ] && OUT=$(basename "${URL%%\?*}")

# 取文件大小
SIZE=$(curl -sIL --max-time 20 "$URL" 2>/dev/null \
       | awk 'tolower($1)=="content-length:" {v=$2} END {print v}' | tr -d '\r')
[ -z "$SIZE" ] && exec curl -L -o "$OUT" "$URL"

# 检查是否支持 Range(取最后一个状态行,跳过重定向)
STATUS=$(curl -sIL --max-time 20 -H "Range: bytes=0-1" "$URL" 2>/dev/null \
         | awk '/^HTTP/ {s=$2} END {print s}')
[ "$STATUS" != "206" ] && exec curl -L -o "$OUT" "$URL"

TMP=$(mktemp -d); CHUNK=$(( (SIZE + N - 1) / N ))
echo "大小 $((SIZE/1048576)) MB,$N 段并发"

i=0
while [ "$i" -lt "$N" ]; do
  S=$((i*CHUNK)); E=$((S+CHUNK-1)); [ "$E" -ge "$SIZE" ] && E=$((SIZE-1))
  curl -sL --max-time 3600 -r "${S}-${E}" \
       -o "$TMP/part.$(printf '%03d' "$i")" "$URL" &
  i=$((i+1))
done
wait

: > "$OUT"; i=0
while [ "$i" -lt "$N" ]; do
  cat "$TMP/part.$(printf '%03d' "$i")" >> "$OUT"; i=$((i+1))
done
rm -rf "$TMP"
echo "完成: $OUT ($(wc -c < "$OUT") 字节)"

几个实现细节

第一个坑我踩过:最初写成 head -1 | grep -c 206, 结果所有带重定向的链接都被判成「不支持分片」,白白退回单线程。

三、下载完记得校验

大文件下载出错不容易发现,尤其是多线程拼接。校验一下更安心:

# SHA256(与官方公布的值对比)
shasum -a 256 ~/Downloads/file.iso

# 如果官方只给了 SHA1
shasum -a 1 ~/Downloads/file.iso

# 查看文件真实类型(扩展名可以骗人)
file ~/Downloads/file.iso

ISO 镜像还可以看卷标和是否可引导:

file win11.iso
# 输出类似:ISO 9660 CD-ROM filesystem data 'XXXX_X64FRE_ZH-CN_DV9' (bootable)
#                                                ↑ 卷标            ↑ 可引导

四、什么时候用哪个

场景建议
大文件、服务器单流限速aria2 或 pget,16 线程
小文件(< 10MB)直接 curl / 浏览器
服务器单流不限速单线程反而更快
需要断点续传、BTaria2(pget 不支持)
不想装任何东西pget