# ⚡ FastSync
**Rust 编写的高性能目录同步工具。**
把源目录镜像到目标目录,或通过网络临时共享一个目录:速度快、可预览、覆盖已有文件时更稳妥。
[](LICENSE)
[](https://www.rust-lang.org/)
[](https://doc.rust-lang.org/edition-guide/rust-2024/index.html)
[](https://github.com/BLAKE3-team/BLAKE3)
[](https://github.com/ShouChenICU/FastSync)
[English](README.md) · [极致性能](#-极致性能) · [网络同步](#-远程同步目录) · [进度](#-进度与日志) · [安全模型](#-默认安全模型) · [安装](#-安装) · [命令速查](#-命令速查)
| 快 | 支持网络同步 | 避免文件损坏 |
| ------------------------------------- | --------------------------- | ---------------------------------- |
| Rust、元数据优先、BLAKE3、并发 worker | 一次性共享/连接,6 位验证码 | 降低意外中断后留下不完整文件的风险 |
## ✨ 为什么选择 FastSync?
FastSync 面向大目录、本地镜像和临时目录交付场景:速度要快,但不能悄悄做危险的事。
- **Rust 编写**:原生二进制执行,资源占用更可控,部署也更简单。
- **为速度设计**:元数据感知比较、BLAKE3、并发 worker。
- **内置网络同步**:用一次性验证码临时共享或接收目录。
- **默认安全**:不隐式删除、支持预览、覆盖已有文件时使用临时文件。
- **运行中和运行后都清楚**:终端进度、给人看的摘要,也支持给脚本用的 JSON。
```mermaid
flowchart LR
A["源目录"] --> B["扫描"]
C["目标目录"] --> B
B --> D["比较"]
D --> E["复制 / 更新"]
D --> F["可选删除"]
E --> G["可读摘要"]
F --> G
```
## 🏎️ 极致性能
目录同步通常混合了文件系统延迟、元数据判断、哈希计算和真实复制。FastSync 将这些阶段保持得清晰、可控。
| 性能设计 | 作用 |
| ---------------- | ------------------------------------------------------------------------ |
| Rust 实现 | 原生执行性能,内存和 CPU 行为更可预期。 |
| 元数据感知比较 | 在大小、修改时间适合作为内容信号时用于快速判断,元数据同步保持独立配置。 |
| BLAKE3 哈希 | 在需要内容确认时,用高速现代哈希算法完成强比较。 |
| 有界 worker 队列 | 并发复制,同时避免任务无限堆积导致内存失控。 |
| 新文件直接复制 | 目标端不存在的新文件直接写入,避免不必要的临时文件重命名开销。 |
> [!NOTE]
> 快速比较是默认模式。需要在元数据一致时也用 BLAKE3 确认内容时,可以使用 `--strict`。
## 🚀 快速开始
预览同步计划:
```bash
fastsync -n ./source ./target
```
真正执行同步:
```bash
fastsync ./source ./target
```
同步并删除目标端陈旧文件:
```bash
fastsync -n -d ./source ./target
fastsync -d ./source ./target
```
> [!CAUTION]
> `--delete` 会删除目标端中“源目录不存在”的项目。首次使用删除模式时,请先用 `-n -d` 预览。
跳过缓存、日志或临时文件:
```bash
fastsync ./source ./target -x .fastsyncignore
```
只同步清单中写到的内容:
```bash
fastsync ./source ./target -i sync-list.txt
```
## 📦 安装
FastSync 使用 Rust 2024 edition,要求 Rust 1.85 或更新版本。如果使用 `rustup`,建议使用稳定工具链:
```bash
rustup default stable
rustup component add rust-src
```
### 使用 Cargo 从 crates.io 安装
```bash
cargo install fastsync
fastsync --help
```
### 从源码构建
```bash
git clone https://github.com/ShouChenICU/FastSync.git
cd FastSync
cargo build --release
./target/release/fastsync --help
```
### 使用 Cargo 从 Git 安装
```bash
cargo install --git https://github.com/ShouChenICU/FastSync
```
## 🌐 语言
FastSync 支持英文和简体中文,会自动识别常见系统语言环境,也可以手动指定:
```bash
fastsync --lang zh-CN --help
FASTSYNC_LANG=zh-CN fastsync --help
```
## 🧭 常见场景
| 目标 | 命令 |
| -------------------------- | ----------------------------------------------- |
| 预览同步 | `fastsync -n ./source ./target` |
| 将一个目录同步到另一个目录 | `fastsync ./source ./target` |
| 同步并删除目标端陈旧项目 | `fastsync -d ./source ./target` |
| 跳过缓存和临时文件 | `fastsync ./source ./target -x .fastsyncignore` |
| 只同步指定内容 | `fastsync ./source ./target -i sync-list.txt` |
| 使用严格比较模式 | `fastsync --strict ./source ./target` |
| 限制 worker 线程数 | `fastsync -t 4 ./source ./target` |
| 为脚本输出 JSON | `fastsync -o json ./source ./target` |
| 临时共享目录 | `fastsync s ./source` |
| 接收共享目录 | `fastsync c host ./target -c 123456` |
交互式文本运行会显示底部进度指示;脚本和 JSON 输出保持干净。详见
[进度与日志](#-进度与日志)。
示例:安全地同步照片备份
```bash
# 第一步:先查看会发生什么。
fastsync -n -d ~/Photos /mnt/backup/Photos
# 第二步:确认无误后执行。
fastsync -d ~/Photos /mnt/backup/Photos
```
示例:快速同步构建缓存
```bash
fastsync ./target/release ./cache/release
```
默认快速模式会信任完全一致的元数据;只有同大小文件的修改时间或支持的权限不一致时,才会用 BLAKE3 确认内容。
## 🎯 只同步你关心的内容
有些目录里会混着缓存、日志、本地草稿,或者你只想把其中一小部分同步出去。FastSync 可以从文本文件读取过滤规则:
| 参数 | 用法 |
| ----------------------------- | -------------------------------------- |
| `-x`, `--exclude-from ` | 黑名单:匹配到的文件或目录不参与同步。 |
| `-i`, `--include-from ` | 白名单:只同步匹配到的文件或目录。 |
规则文件一行一条规则,空行和 `#` 开头的注释会被忽略。常用写法示例:
```gitignore
# 跳过构建产物和缓存
target/
cache/
*.tmp
logs/**/*.log
```
```bash
fastsync ./project /mnt/backup/project -x .fastsyncignore
```
白名单适合“只交付这些内容”的场景:
```gitignore
dist/
README.md
docs/**/*.md
```
```bash
fastsync ./project ./release -i sync-list.txt
```
过滤规则会保护匹配范围之外的内容:它们不会被复制、覆盖、校验、同步元数据,也不会因为 `--delete` 被删除。也就是说,黑名单中的本地缓存会被原样保留;白名单之外的目标端文件也会保持不动。
当前支持常用 gitignore 写法:`*`、`?`、`**`、以 `/` 开头的根路径规则,以及以 `/` 结尾的目录规则。目录规则会包含整棵子树。暂不支持 `!` 反向规则。
## 🌐 远程同步目录
当你想把一个目录临时发给别人,或临时接收别人上传的目录时,可以使用网络同步。共享目录的一方运行 `share`,把一次性验证码告诉对方;另一方运行 `connect` 后即可开始同步。
> [!IMPORTANT]
> 这是单向同步。每次只选择下载或上传,不做双方修改的自动合并。
把目录发给别人:
```bash
fastsync s ./photos
fastsync c server.example.com ./photos -c 123456
```
让别人上传目录给你:
```bash
fastsync s ./inbox -r
fastsync c server.example.com ./project -u -c 123456
```
默认行为:
| 默认值 | 含义 |
| ------------------ | ------------------------------------------ |
| 共享方发文件 | `fastsync s ./photos` 默认只允许对方下载。 |
| 一次性验证码 | 共享开始时自动打印验证码。 |
| 成功一次即退出 | 完成一次同步后,共享方自动结束。 |
| 不允许删除共享文件 | 上传方不能删除你的文件,除非你显式允许。 |
可以省略 `--code`,FastSync 会交互式提示输入。
常用快捷方式:
| 完整写法 | 快捷写法 |
| ------------------------ | ----------------- |
| `share` / `connect` | `s` / `c` |
| `--code 123456` | `-c 123456` |
| `--mode receive` | `-r` 或 `-m r` |
| `--direction push` | `-u` |
| `--delete` | `-d` |
| `--strict` | 无短写 |
| `--allow-delete` | `-a` |
| `--preserve-permissions` | `-p` 或 `--perms` |
| `--exclude-from FILE` | `-x FILE` |
| `--include-from FILE` | `-i FILE` |
删除多余文件需要显式开启,并且只会影响接收文件的一方:
| 你选择 | `--delete` 可能删除哪里 | 额外要求 |
| ------ | ----------------------- | ------------------ |
| 下载 | 你本地目录中的多余项目 | 无 |
| 上传 | 共享目录中的多余项目 | 共享方必须允许删除 |
```bash
fastsync c server.example.com ./photos -d -c 123456
fastsync s ./inbox -r -a
fastsync c server.example.com ./project -u -d -c 123456
```
网络同步也支持 `-x/--exclude-from` 和 `-i/--include-from`。共享方和连接方各自只在本地应用自己的规则,规则不会发给对方,也不会合并成共同清单。比如共享方可以不分享 `private/`,连接方也可以只接收 `photos/`;每一侧的过滤规则都只影响这一侧能发送、请求、写入或删除的路径。
默认会保留接收文件的修改时间。权限位只在显式要求时复制:
| 参数 | 含义 |
| ------------------------ | ------------------------------------------------------------ |
| `--strict` | 决定传输哪些文件前,同大小本地文件即使元数据一致也计算哈希。 |
| `--no-preserve-times` | 不在接收的文件和目录上保留源端修改时间。 |
| `--preserve-permissions` | 在接收的文件和目录上保留源端权限位。默认关闭。 |
不使用 `--strict` 时,网络同步默认使用快速比较:元数据一致则认为文件一致;只有同大小但元数据不一致时才用 BLAKE3 确认内容。
为了便于审计,共享方会记录连接来源、下载/上传方向、删除/元数据选项、配对失败原因、文件数、字节数、删除数和耗时。需要更多细节可用 `--log-level debug`。
技术说明:一次性网络同步基于 QUIC,使用临时自签名证书和一次性验证码;接收文件会用 BLAKE3 校验,并先写临时文件再替换目标文件。适合双方能确认地址与验证码的短会话。
## 🛡️ 默认安全模型
| 默认行为 | 为什么重要 |
| ---------------- | -------------------------------------------------------------------------------------- |
| 单向同步 | 源目录是权威数据,目标目录跟随源目录。 |
| 不隐式删除 | 不传 `--delete` 时,目标端额外文件会被保留。 |
| 过滤外内容不动 | 黑名单匹配项和白名单之外的内容不会被复制、覆盖或删除。 |
| 快速内容比较 | 两端已有文件默认信任一致的元数据;同大小但元数据不一致时才用 BLAKE3 确认内容。 |
| 临时文件覆盖写入 | 覆盖已有文件时,默认先写入临时文件名,再重命名到目标路径,降低中断后留下半文件的风险。 |
| 新文件直接复制 | 目标端不存在的新文件直接复制,避免不必要的重命名开销。 |
| 支持预览模式 | 可以在修改目标目录前查看计划。 |
## 🔍 选择比较模式
| 模式 | 行为 | 适合场景 |
| -------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `fast` | 元数据一致时认为文件一致;元数据不一致时,大小不同直接认为内容不一致,大小相同再用 BLAKE3 确认内容。默认模式。 | 希望保持速度,同时对同大小的可疑变化做内容确认。 |
| `strict` | 大小一致时始终使用 BLAKE3 确认内容,即使元数据也一致。 | 重要数据,需要元数据一致时也做内容确认。 |
`--strict` 是 `--compare strict` 的快捷方式。
> [!IMPORTANT]
> 快速模式可能漏掉“内容变化但大小、修改时间和支持的权限都未变化”的文件。重要数据如果需要元数据一致时也确认内容,请使用 `strict`。
同名文件的元数据同步与内容比较策略相互独立,并且默认开启;它会把源端元数据应用到匹配的目标文件。可以用 `--no-sync-metadata` 跳过内容已相同文件的独立元数据更新,或用 `--preserve-times false` 和/或 `--preserve-permissions false` 缩小同步到目标端的源端元数据范围。
## ✅ 校验策略
使用 `--verify` 控制复制后的校验:
| 模式 | 行为 |
| --------- | ---------------------------------- |
| `none` | 复制后不校验。 |
| `changed` | 校验发生覆盖的文件,默认模式。 |
| `all` | 同步后校验源目录中的所有普通文件。 |
摘要会分开统计两类 BLAKE3 内容检查:`fast` 或 `strict` 在比较阶段执行的内容比较,以及由 `--verify` 控制的复制后校验。
目标端不存在的新文件会直接复制,不会计入复制后的 BLAKE3 校验次数。
## 📟 进度与日志
在交互式终端使用文本输出时,fastsync 会为本地同步阶段显示底部进度指示:
- 扫描源目录和目标目录。
- 生成同步计划,包括已处理条目、计划操作数、计划数据量和 BLAKE3 比较次数。
- 执行同步计划。
- 使用 `--verify all` 时执行全量校验。
网络 `share` 和 `connect` 命令也会为正在进行的传输阶段显示进度:
- 发送和接收 manifest。
- 为可疑文件响应或请求 BLAKE3 哈希。
- 规划需要请求的文件。
- 发送和接收文件流。
- 在相关阶段运行时,删除陈旧项并应用收到的元数据。
进度 UI 面向终端用户。JSON 输出、非 TTY 输出、`TERM=dumb` 和 `NO_COLOR`
环境会自动隐藏进度条。摘要和 JSON 继续写入 stdout,日志和进度写入
stderr,因此脚本可以安全读取 stdout。
启用进度 UI 时,fastsync 会通过兼容进度条的 writer 输出 tracing 日志,
避免日志行破坏底部进度指示。需要更多细节时可以提高 `--log-level`;
进度只是可视化状态层,不改变同步行为。
## 🧾 命令速查
| 参数 | 含义 |
| -------------------------------------------- | -------------------------------------------- |
| `-n`, `--dry-run` | 只预览,不修改目标目录。 |
| `-d`, `--delete` | 删除目标端中源目录不存在的项目。 |
| `-x`, `--exclude-from ` | 从规则文件读取黑名单,匹配内容不参与同步。 |
| `-i`, `--include-from ` | 从规则文件读取白名单,只同步匹配内容。 |
| `--strict` | 对同大小的已有文件使用严格 BLAKE3 内容确认。 |
| `-c`, `--compare ` | 选择比较策略。 |
| `--no-sync-metadata` | 不更新内容已相同的同名文件元数据。 |
| `--preserve-times ` | 将源文件修改时间同步到目标文件。 |
| `--preserve-permissions ` | 将源文件权限位同步到目标文件。 |
| `--verify ` | 选择复制后校验策略。 |
| `-t`, `--threads ` | 设置 worker 线程数。 |
| `-q`, `--queue-size ` | 设置有界任务队列长度。 |
| `--no-atomic-write` | 禁用覆盖时的临时文件写入。 |
| `-o`, `--output ` | 设置摘要输出格式。 |
| `-l`, `--log-level ` | 设置日志级别。 |
| `--lang ` | 设置界面语言,也支持常见 locale 别名。 |
一次性网络同步命令:
| 命令 | 含义 |
| -------------------------------------------- | ----------------------------------------- |
| `fastsync share ` | 启动临时服务端,默认 `--mode send`。 |
| `fastsync connect ` | 连接临时服务端,默认 `--direction pull`。 |
| `fastsync s ` | `fastsync share` 的短写。 |
| `fastsync c ` | `fastsync connect` 的短写。 |
| `fastsync c --strict` | 请求文件前使用严格比较。 |
| `fastsync share --help` | 查看服务端所有参数。 |
| `fastsync connect --help` | 查看客户端所有参数。 |
查看完整帮助:
```bash
fastsync --help
fastsync share --help
fastsync connect --help
```
不带任何参数运行 `fastsync` 时,也会输出帮助页面。
## 🧪 开发
`Cargo.toml` 中的 `edition = "2024"` 是 Rust edition 名称,不是当前日历年份。Rust edition 是可选择的语言兼容性里程碑;即使在 2026 年构建项目,Rust 2024 edition 仍然是正确写法。
```bash
cargo fmt --check
cargo test
cargo clippy --all-targets --all-features -- -D warnings
```
维护者和代码 agent 请阅读 [AGENTS.md](AGENTS.md)。
## ❓ 常见问题
FastSync 是双向同步吗?
不是。FastSync 是单向同步:从源目录同步到目标目录。
FastSync 默认会删除文件吗?
不会。只有显式传入 `--delete` 或 `-d` 时才会删除目标端额外项目。
我应该使用 --strict 吗?
如果是重要个人数据或生产数据,且你希望元数据一致时也确认内容,可以使用。对于生成文件、缓存、构建产物,默认的 `fast` 模式通常是更合适的折中。
## 📄 开源协议
FastSync 使用 [MIT License](LICENSE) 开源。
作者:[ShouChen](https://github.com/ShouChenICU)
项目地址:[https://github.com/ShouChenICU/FastSync](https://github.com/ShouChenICU/FastSync)