TransferSu - 统一文件传输工具

基于 rsync / rclone / pv+tar 的统一拷贝管理工具,CLI/TUI 双模式,实时日志轮转, 专为"读卡器掉卡"等不稳定传输场景设计。

特性

  • 多后端: rsync(推荐, 断点续传)/ rclone(并行)/ pv+tar(零依赖)
  • CLI/TUI 双模式: 未显式 --mode cli 时默认 TUI 启动
  • TUI 四栏布局:
    • 上栏: 总进度条(字节) + 单文件进度条(文件计数)
    • 中栏: 速度曲线可视化(当前/峰值/平均速度实时文字)
    • 下栏: 文件日志 + 错误日志 双面板
    • 底部: 交互输入栏(空启动设定任务 / 传输控制命令)
  • 进度轮询机制: 每秒主动统计目标目录大小驱动进度, 绕过后端输出缓冲(Android 上 stdbuf/LD_PRELOAD 无效,rsync 输出全缓冲不可靠)
  • 掉卡自愈: --retry -1 无限自动补传 + 完成后 --verify 校验
  • 实时日志: 写入本地目录, 滚动保留最近 N 个(默认 20), 纳秒时间戳排序

安装

pip install -i https://mirrors.aliyun.com/pypi/simple/ pytest textual

用法

# TUI 模式 (默认): 空启动后在底部输入栏设定任务
python3 transfer.py

# TUI 模式带预设任务
python3 transfer.py /src /dst --bwlimit 30000

# CLI 模式 (显式指定)
python3 transfer.py --mode cli /src/ /dst/ --backend rclone --bwlimit 8M

TUI 输入栏命令

/src /dst --bwlimit 30000 --retry -1 --verify   # 启动传输任务
stop          # 停止当前任务 (SIGTERM, 跳过补传)
pause         # 暂停 (SIGSTOP, 轮询同步挂起)
continue      # 恢复暂停 (SIGCONT)
help / clear / quit

进度显示:

  • 总进度条: 已传字节/源总量(每秒轮询刷新)
  • 单文件进度条: 文件计数(目标文件数/源文件总数, 每 3 秒刷新)
  • 速度曲线栏: 当前/峰值/平均速度文字 + Sparkline 曲线

参数

参数 默认 说明
--backend rsync rsync / rclone / tar
--bwlimit 30000 限速 (rsync: KB/s, rclone: 如 8M)
--transfers 4 rclone 并行传输数
--resume / --no-resume 开 rsync 断点续传
--checksum 关 rsync 校验模式
--verify 关 传输完成后校验(等级由 --verify-level 决定)
--verify-level slow 校验等级: ultrafast/fast/normal/slow/full
--check-only 关 纯校验模式: 不传输, 仅按等级校验源/目标
--retry 0 失败自动补传轮数, -1 = 无限重试
--smart-resume 关 智能续传: 校验目标最新N个文件, 损坏删除后从断点续传
--smart-check 5 智能续传校验文件数 (<=100MB 全校验, 更大只查大小)
--policy overwrite 冲突策略: overwrite / skip / ask
--mode tui cli / tui
--keep-logs 20 日志滚动保留数
--logdir ~/logs 日志目录

掉卡场景最佳实践

读卡器/移动硬盘在安卓上高速写入可能 USB 掉线(如 GL3224 芯片)。 完整方案:

  1. 守护脚本自动恢复设备(掉线后重枚举):
    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 差异 = 源目标完全一致)

智能续传(--smart-resume): 中断后重跑时,只校验目标最新 N 个文件 (--smart-check N,默认 5;≤100MB 做 md5 全校验,更大只查大小), 发现损坏立即删除该文件并从断点续传——避免对已传的 100+GB 全量重扫。 校验过程有进度条(总进度条复用)+ 单文件日志(校验 i/N: 文件名 ✓/✘ 损坏), N 调大(如 50)也能实时看到校验进展。

校验等级(--verify-level)

等级 校验内容 188GB 耗时 适用
ultrafast 仅文件大小 秒级 快速健康检查
fast 大小+mtime ~1 分钟 常规检查
normal 大小+mtime+最新N个md5 分钟级 兼顾速度与深度
slow 全部文件 md5 40-60 分钟 全量可靠(默认)
full 全部md5+文件数对比 最慢 终极确认

纯校验模式(--check-only): 不传输,只按等级校验源/目标一致性, 用于传输中断后快速确认已传数据是否完好:

# 快速检查已传数据(秒级)
python3 transfer.py --mode cli --check-only --verify-level ultrafast /src/ /dst/
# 全量校验已传数据(全部 md5)
python3 transfer.py --mode cli --check-only --verify-level slow /src/ /dst/

rsync 原子写(临时文件+rename)保证掉卡不会产生半截损坏的正式文件, 残留临时文件由补传后的 --verify 流程发现处理。

日志

  • 目录: --logdir 指定(默认 ~/logs)
  • 文件名: {时间戳}_{后端}_{源名}.log(时间戳开头, 排序即时间序)
  • 滚动: 超过 --keep-logs 个自动删除最旧
  • 内容: 命令/源大小/补传轮次/退出码(含帧数)/校验结果/错误行

冲突策略(覆盖/跳过)

参数 行为
--overwrite 覆盖已存在文件(默认)
--skip 跳过已存在文件(--ignore-existing)
--ask 逐项询问(扫描冲突后交互)

ask 交互选项(CLI 与 TUI 一致):

y = 覆盖当前项      n = 跳过当前项
a = 全部覆盖        s = 全部跳过
q = 中止传输
  • CLI: 预扫描后逐项提示
  • TUI: 扫描完成后在底部输入栏逐项交互
  • 仅当前/后续同步: y/n 只作用当前文件; a/s 一次决定后续(已明确决策的保留)
  • rsync 覆盖场景自动禁用 --append(追加模式阻止重写), 保留 --partial
  • rclone 的 --ask 用原生 --interactive(y/n/s); tar 后端不支持 ask/skip
# 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 --retry -1 --verify

测试

python3 -m pytest tests/ -q

54 个单元测试: 解析器 / 日志轮转 / 参数解析 / 后端命令 / 冲突决策 / 目录轮询 / 暂停信号 / 校验命令。

S
Description
一个支持多种参数设定的可视化文件复制 Python 脚本项目。
Readme MIT
376 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 96.7%
Shell 3.3%