docs: README 全面更新 (轮询机制/无限重试/TUI命令/掉卡最佳实践)

This commit is contained in:
AskaEth committed 2026-08-22 14:11:18 +08:00
1 parent ae875cb710
commit 15ed4330ae
1 file changed
+59 -35
+59 -35
View File
@@ -1,18 +1,21 @@
# TransferSu - 统一文件传输工具
基于 rsync / rclone / pv+tar 的统一拷贝管理工具,CLI/TUI 双模式,实时日志轮转。
基于 rsync / rclone / pv+tar 的统一拷贝管理工具,CLI/TUI 双模式,实时日志轮转,
专为"读卡器掉卡"等不稳定传输场景设计。
## 特性
- **多后端**: rsync(推荐, 断点续传)/ rclone(并行)/ pv+tar(零依赖)
- **CLI/TUI 双模式**: 未显式 `--mode cli` 时默认 TUI 启动
- **TUI 四栏布局**:
- 上栏: 总进度条 + 单文件进度条
- 中栏: 速度曲线可视化(最近 80 秒采样)
- 上栏: 总进度条(字节) + 单文件进度条(文件计数)
- 中栏: 速度曲线可视化(当前/峰值/平均速度实时文字)
- 下栏: 文件日志 + 错误日志 双面板
- 底部: 交互输入栏(可空启动后设定任务)
- **实时日志**: 写入本地目录, 滚动保留最近 N 个(默认 20), 文件名含纳秒时间戳
- **可控性**: 限速 / 断点续传 / 校验 / 并行数 全部可配
- 底部: 交互输入栏(空启动设定任务 / 传输控制命令)
- **进度轮询机制**: 每秒主动统计目标目录大小驱动进度,
绕过后端输出缓冲(Android 上 stdbuf/LD_PRELOAD 无效,rsync 输出全缓冲不可靠)
- **掉卡自愈**: `--retry -1` 无限自动补传 + 完成后 `--verify` 校验
- **实时日志**: 写入本地目录, 滚动保留最近 N 个(默认 20), 纳秒时间戳排序
## 安装
@@ -36,17 +39,19 @@ python3 transfer.py --mode cli /src/ /dst/ --backend rclone --bwlimit 8M
### TUI 输入栏命令
```
/src /dst --backend rclone --bwlimit 8M --transfers 4 # 启动传输任务
stop # 停止当前任务
pause # 暂停 (SIGSTOP)
continue # 恢复暂停
/src /dst --bwlimit 30000 --retry -1 --verify # 启动传输任务
stop # 停止当前任务 (SIGTERM, 跳过补传)
pause # 暂停 (SIGSTOP, 轮询同步挂起)
continue # 恢复暂停 (SIGCONT)
help / clear / quit
```
单文件进度条显示**文件计数进度**(目标文件数/源文件总数,每 3 秒刷新),
大文件库下按文件粒度推进。
进度显示:
- 总进度条: 已传字节/源总量(每秒轮询刷新)
- 单文件进度条: **文件计数**(目标文件数/源文件总数, 每 3 秒刷新)
- 速度曲线栏: 当前/峰值/平均速度文字 + Sparkline 曲线
### 参数
## 参数
| 参数 | 默认 | 说明 |
|---|---|---|
@@ -55,35 +60,48 @@ help / clear / quit
| `--transfers` | 4 | rclone 并行传输数 |
| `--resume` / `--no-resume` | 开 | rsync 断点续传 |
| `--checksum` | 关 | rsync 校验模式 |
| `--verify` | 关 | 完成后校验(rsync -c dry-run,0 差异=一致) |
| `--retry` | 0 | 失败自动补传轮数(配合守护自动恢复设备) |
| `--verify` | 关 | 完成后校验(rsync -c dry-run, 0 差异=一致) |
| `--retry` | 0 | 失败自动补传轮数, **-1 = 无限重试** |
| `--policy` | overwrite | 冲突策略: overwrite / skip / ask |
| `--mode` | tui | cli / tui |
| `--keep-logs` | 20 | 日志滚动保留数 |
| `--logdir` | ~/logs | 日志目录 |
## 掉卡场景最佳实践
读卡器/移动硬盘在安卓上高速写入可能 USB 掉线(如 GL3224 芯片)。
完整方案:
1. **守护脚本**自动恢复设备(掉线后重枚举):
```bash
su -c 'setsid sh /data/local/tmp/usb_guard.sh </dev/null >/dev/null 2>&1 &'
```
2. **限速传输 + 无限补传 + 校验**:
```
/src/ /dst/ --bwlimit 30000 --retry -1 --verify
```
3. 掉卡时: 守护恢复设备 → TransferSu 自动重跑补传(`--partial` 只补缺失)→
直到成功 → `rsync -c` 全量校验(0 差异 = 源目标完全一致)
> rsync 原子写(临时文件+rename)保证掉卡不会产生半截损坏的正式文件,
> 残留临时文件由补传后的 `--verify` 流程发现处理。
## 日志
- 目录: `--logdir` 指定(默认 `~/logs`)
- 文件名: `{时间戳}_{后端}_{源名}.log`(时间戳开头保证排序即时间序)
- 文件名: `{时间戳}_{后端}_{源名}.log`(时间戳开头, 排序即时间序)
- 滚动: 超过 `--keep-logs` 个自动删除最旧
## 测试
```bash
python3 -m pytest tests/ -q
```
- 内容: 命令/源大小/补传轮次/退出码(含帧数)/校验结果/错误行
## 冲突策略(覆盖/跳过)
传输前可用参数预设策略,或中途逐项决策:
| 参数 | 行为 |
|---|---|
| `--overwrite` | 覆盖已存在文件(默认) |
| `--skip` | 跳过已存在文件(`--ignore-existing`) |
| `--ask` | 逐项询问(扫描冲突后交互) |
**ask 交互选项**(CLI 与 TUI 一致):
**ask 交互选项**(CLI 与 TUI 一致):
```
y = 覆盖当前项 n = 跳过当前项
@@ -91,21 +109,27 @@ a = 全部覆盖 s = 全部跳过
q = 中止传输
```
- **CLI**:预扫描后逐项提示,输入 y/n/a/s/q
- **TUI**:扫描完成后在底部输入栏逐项交互(stats 栏显示当前冲突文件)
- **仅当前/后续同步**:y/n 只作用于当前文件;a/s 一次决定后续所有冲突
- rsync 覆盖场景自动禁用 `--append`(追加模式会阻止重写),保留 `--partial`
- rclone 的 `--ask` 使用原生 `--interactive`(y/n/s);tar 后端不支持 ask/skip
- **CLI**: 预扫描后逐项提示
- **TUI**: 扫描完成后在底部输入栏逐项交互
- **仅当前/后续同步**: y/n 只作用当前文件; a/s 一次决定后续(已明确决策的保留)
- rsync 覆盖场景自动禁用 `--append`(追加模式阻止重写), 保留 `--partial`
- rclone 的 `--ask` 用原生 `--interactive`(y/n/s); tar 后端不支持 ask/skip
```bash
# CLI 示例: ask 交互 + 补传 + 校验
# CLI 示例
python3 transfer.py --mode cli --policy ask --retry 5 --verify /src/ /dst/
python3 transfer.py --mode cli --retry -1 --verify /src/ /dst/
# TUI 输入栏示例
/src /dst --policy ask --retry 5 --verify
/src /dst --skip
/src /dst --retry -1 --verify
```
> `--retry` 在传输失败(掉卡等)后自动重跑补传,`--verify` 完成后用
> `rsync -c --dry-run` 全量校验(无输出=源目标完全一致),适合读卡器
> 掉卡频繁的场景。
## 测试
```bash
python3 -m pytest tests/ -q
```
54 个单元测试: 解析器 / 日志轮转 / 参数解析 / 后端命令 / 冲突决策 /
目录轮询 / 暂停信号 / 校验命令。