@lpb_name/down
Version:
A Node.js download manager with multi-threading support
168 lines (121 loc) • 7.66 kB
Markdown
# down
一个基于 Node.js 的多线程下载管理器,支持分片并发、断点续传、自动降级与进度条显示。命令行名称为 `down`,可直接使用 `down <url>` 进行下载。
## 特性
- 多线程分片下载(支持 HTTP Range),按偏移写入,文件内容不乱序。
- 自动能力探测:检查 `content-length` 与 `accept-ranges`,不支持则自动降级为单线程下载。
- 断点续传:下载过程中生成并更新 `output.down.meta.json` 元数据文件,重新运行可从未完成位置继续。
- 预分配文件大小:减少磁盘碎片,提高写入稳定性。
- 进度显示:总进度条(总体 MB/百分比)、每个线程进度条、分片完成统计。
- 稳定性增强:Keep-Alive 连接、请求超时与重试策略(默认 3 次重试)。
- 完成后校验:下载结束时校验输出文件大小与期望是否一致。
- 失败清理:下载失败时自动清理 0B 空文件,保留元数据以便继续下载。
## 安装
- 全局安装(示例):`pnpm i -g down` 或 `npm i -g down`
- 项目内安装:`pnpm add down` 或 `npm i down`
## 使用
基础用法(发布后全局命令为 `down`):
```
down <url> [options]
```
常用参数:
- `-o, --output <filename>` 指定输出文件名(默认从 URL 路径推断)。
- `-t, --threads <number>` 下载线程数,范围 1–20,默认 3。
- `-d, --directory <path>` 下载目录,默认当前目录。
- `-T, --timeout <ms>` 连接/首字节等待超时(毫秒),下载过程中不限制,默认 600000。
示例:
- `down https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf`
- `down http://ipv4.download.thinkbroadband.com/10MB.zip -t 6 -d ./downloads`
- `down https://example.com/file.zip -o myfile.zip`
### 命令行选项
| 选项 | 简写 | 描述 | 默认值 |
|------|------|------|--------|
| `--output` | `-o` | 输出文件名 | 从 URL 自动推断 |
| `--threads` | `-t` | 下载线程数 (1–20) | 3 |
| `--directory` | `-d` | 下载目录 | 当前目录 |
| `--timeout` | `-T` | 连接/首字节等待超时(下载开始前) | 600000 |
| `--version` | `-V` | 显示版本信息 | - |
| `--help` | `-h` | 显示帮助信息 | - |
## 进度显示
下载过程中会显示:
- 总进度(已下载/总大小,百分比)
- 每个线程的下载进度和速度
- 分片完成统计
示例输出:
```
总进度 |██████████████████░░░░░░░░| 42% | 12.34/29.00MB
Thread 1 |███████████░░░░░░░░░░░░| 65% | 4.22/6.50MB | 速度: 1.20MB/s
Thread 2 |██████░░░░░░░░░░░░░░░░| 35% | 2.28/6.50MB | 速度: 测量中
分片完成 |█████░░░░░░░░░░░░░░░░| 30% | 已完成: 3/10个分片
```
## 断点续传说明
- 下载时会在同目录生成 `output.down.meta.json`(例如 `downloads/file.zip.down.meta.json`),记录每个分片的 `start/end/downloaded/completed`。
- 重新运行同一 `url` 与同一 `threads` 时,会自动从未完成的位置继续下载。
- 若修改了 `threads`、`url` 或服务器返回的总大小发生变化,元数据会被重新初始化,无法直接续传。
- 想强制重新开始:删除对应的 `.down.meta.json` 文件或更换输出路径/文件名。
## 实现与行为
- 能力探测:先发起 `HEAD` 检查 `content-length` 与 `accept-ranges`;失败或缺失时回退为短暂 `GET` 探测;不支持则自动单线程。
- 分片规划:按总大小与线程数等分,最后一片补齐;每片记录 `start/end/downloaded/completed`。
- 写入方式:预分配文件大小后,按偏移以 `r+` 模式直接写入目标文件,无需后续合并。
- 元数据:保存在 `<输出文件>.down.meta.json`;下载过程中约每 256KB 刷新一次;成功后自动删除元数据文件。
- 覆盖策略:若输出文件已存在将被覆盖;如需保留旧文件,请使用 `-o` 指定新文件名或调整 `-d` 目录。
- 校验:当服务器返回总大小时,下载完成后进行大小校验并提示不一致情况。
- 退出码:成功退出码为 `0`,失败为 `1`。
## 性能与调优
- 线程建议:一般 `3–6` 较为稳妥;局域网/CDN可增至 `8–12`;高延迟或受限网络建议 `2–4`。
- 服务端限速/并发限制:若出现 `429/503` 或频繁断流,请降低线程数或稍后重试。
- 连接复用:启用 Keep-Alive 以减少握手开销;适度提升线程可更充分利用带宽。
- 磁盘空间:预分配会一次性占用目标文件总大小,确保磁盘空间充足。
## 限制与注意事项
- 不支持 Range 或未知长度时,将无法并发与断点续传,工具会自动单线程以保证完成。
- 续传假设远端内容未变化:当前未校验 ETag/Last-Modified;若内容变更可能导致不一致,必要时删除 `.down.meta.json` 后重新下载。
- 某些代理/网关会移除 `Accept-Ranges` 或阻断 `206` 响应;遇到此类环境建议使用 `-t 1`。
- HTTPS 证书问题会导致失败:请更换下载源或更新系统根证书。
- 校验建议:暂未内置校验参数,建议使用 `shasum -a 256 <file>` 进行完整性验证。
## 帮助输出示例
```
Usage: down [options] <url>
A powerful multi-threaded download manager
Arguments:
url URL to download
Options:
-o, --output <filename> Output filename
-t, --threads <number> Number of download threads (default: "3")
-d, --directory <path> Download directory (default: current working directory)
-T, --timeout <ms> Connect/first-byte timeout in milliseconds (default: "600000")
-V, --version output the version number
-h, --help display help for command
示例:
$ down https://example.com/file.zip
$ down https://example.com/file.zip -o myfile.zip
$ down https://example.com/file.zip -t 10 -d ./downloads
```
## 代理与网络建议
- 如需通过代理下载,请按需配置系统或网络代理工具。
- 若遇到证书或网络异常,可关闭代理或更换支持 Range 的链接。
## Node 版本
- 要求 Node >= 14,建议使用 Node 18+ LTS。
## 开发与本地调试
- 本地直接运行:`node bin/cli.js <url> -t 4 -d ./downloads`
- 或全局链接测试:
- `pnpm link --global`
- 之后可直接使用 `down <url>` 测试。
## 常见问题
- 显示“服务端不支持分片或无法获取长度,降级为单线程下载”:服务器未返回 `content-length` 或不支持 Range,工具会自动降级,确保稳定完成。
- 下载失败留下了 0B 空文件:工具会自动清理 0B 文件;若残留可手动删除。部分失败情况下会保留 `.down.meta.json` 以便续传。
- 如何判断链接是否支持分片:`curl -I <url> | grep -i 'accept-ranges\|content-length'`。
## 许可证
MIT
## 更新日志
### v1.1.0
- 切换 HTTP 客户端为 `got`,启用 Keep-Alive
- 修复并发写入:按文件偏移写入,避免乱序
- 能力探测:检测 `content-length` 与 `accept-ranges`,不支持自动降级单线程
- 断点续传:生成/更新 `.down.meta.json` 元数据,自动从已下载偏移续传
- 预分配文件大小:减少磁盘碎片,提高写入稳定性
- 进度展示:总进度条、分线程进度条、分片完成统计
- 完成后校验与失败清理:校验输出大小;失败时清理 0B 文件
### v1.0.0
- 初始版本发布
- 支持多线程下载
- 命令行界面
- 实时进度显示