npm package: @lpb_name/down
Description: A Node.js download manager with multi-threading support
Author: Lpbzzz
Latest version: 1.3.1

# 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
- 初始版本发布
- 支持多线程下载
- 命令行界面
- 实时进度显示