目录同步这件事,最怕两个极端:慢得像在手搓每一个文件,或者快得让人心里发毛。
FastSync 想解决的就是这个夹缝问题:大目录要同步得快,但任何可能破坏目标目录的动作都必须显式、可预览、可追踪。
项目地址:https://github.com/ShouChenICU/FastSync
crates.io:https://crates.io/crates/fastsync
一、FastSync 是什么
FastSync 是一个 Rust 编写的单向目录同步工具。它可以把一个源目录同步到目标目录,也可以临时开启一次网络共享,让另一台机器拉取或上传一个目录。
一句话理解:
FastSync 不是双向合并工具,它的模型是“源目录是权威数据,目标目录跟随源目录”。
这点很重要。很多同步事故都来自“工具替我猜我要保留哪边”。FastSync 不猜。默认情况下,它只复制和更新,不会偷偷删除目标目录里多出来的文件。需要镜像删除时,你必须显式加 --delete,而且建议先 --dry-run 预览。
它适合这些场景:
| 场景 | 用法 |
|---|---|
| 本地备份 | 把照片、项目、资料目录同步到另一个磁盘 |
| 构建缓存 | 快速把缓存目录同步到临时工作区 |
| 发布产物 | 把构建结果镜像到部署目录 |
| 临时传文件 | 用一次性验证码把目录发给另一台机器 |
| 脚本集成 | 用 JSON 输出把同步结果交给自动化流程 |
不太适合的场景也要说清楚:如果你需要 Dropbox / Syncthing 那种长期双向同步、冲突解决、版本历史,FastSync 不是那个东西。它更像一把锋利但有护手的 CLI 工具:短平快,边界明确。
二、安装 FastSync
FastSync 发布在 crates.io 上,最直接的安装方式是用 Cargo。
先确保 Rust 工具链够新。FastSync 使用 Rust 2024 edition,要求 Rust 1.85 或更新版本:
rustup default stable
rustup component add rust-src
然后安装:
cargo install fastsync
fastsync --help
也可以直接从 GitHub 安装最新代码:
cargo install --git https://github.com/ShouChenICU/FastSync
如果想从源码构建:
git clone https://github.com/ShouChenICU/FastSync.git
cd FastSync
cargo build --release
./target/release/fastsync --help
FastSync 支持英文和简体中文。它会自动识别系统语言,也可以手动指定:
fastsync --lang zh-CN --help
FASTSYNC_LANG=zh-CN fastsync --help
Windows PowerShell 里设置环境变量可以这样写:
$env:FASTSYNC_LANG = "zh-CN"
fastsync --help
三、最快上手:先预览,再执行
准备两个目录:
source/
a.txt
images/logo.png
target/
old.txt
先预览同步计划:
fastsync -n ./source ./target
-n 是 --dry-run,只告诉你 FastSync 准备做什么,不会改动目标目录。
确认没问题后执行:
fastsync ./source ./target
这时 source 里的文件会被复制或更新到 target。但注意:target/old.txt 默认会被保留,因为 FastSync 不会隐式删除目标端多出来的东西。
如果你想让目标目录严格变成源目录的镜像,先预览删除计划:
fastsync -n -d ./source ./target
确认后再执行:
fastsync -d ./source ./target
-d 是 --delete,它会删除目标目录中“源目录不存在”的项目。
第一次使用删除模式时,一定先跑 -n -d。 这不是仪式感,是避免手滑清空错误目录的最后一道刹车。
四、为什么它快:先信元数据,再哈希可疑文件
目录同步慢,通常不是单点慢,而是几件事叠在一起慢:扫描目录、比较文件、计算哈希、复制数据、写入元数据。
FastSync 的默认比较策略叫 fast。它的判断大概是这样:
| 情况 | 默认行为 |
|---|---|
| 文件大小和修改时间等元数据一致 | 认为内容没变 |
| 文件大小不同 | 认为内容变了,直接更新 |
| 大小相同但元数据不同 | 用 BLAKE3 确认内容 |
这个策略很实用:大多数真实目录里,文件变了,大小或修改时间也会变;没必要对每个文件都重新哈希一遍。
但它也有边界。如果一个文件内容变了,但大小、修改时间和相关元数据都被刻意保持一致,快速模式可能判断不出来。
重要数据可以用严格模式:
fastsync --strict ./source ./target
--strict 等价于 --compare strict,会对同大小的已有文件使用 BLAKE3 做内容确认,即使元数据看起来也一致。
我的建议很简单:
| 数据类型 | 推荐模式 |
|---|---|
| 构建缓存、临时产物、可再生成文件 | 默认 fast |
| 照片备份、文档归档、重要源码快照 | --strict |
| 第一次建立镜像 | 先 -n,必要时加 --strict |
| 每日增量同步 | 默认 fast 通常更合适 |
五、覆盖写入和校验:快,但不莽
FastSync 的安全模型有几个很关键的默认值:
| 设计 | 意义 |
|---|---|
| 不隐式删除 | 目标端额外文件默认保留 |
| 支持 dry-run | 真正修改前可以先看计划 |
| 覆盖已有文件用临时文件 | 降低中断后留下半个坏文件的风险 |
| 新文件直接复制 | 避免不必要的临时重命名开销 |
| 默认校验覆盖文件 | 更新后用 BLAKE3 验证发生覆盖的文件 |
复制后的校验由 --verify 控制:
fastsync --verify none ./source ./target
fastsync --verify changed ./source ./target
fastsync --verify all ./source ./target
三种策略分别是:
| 策略 | 含义 |
|---|---|
none | 复制后不额外校验 |
changed | 校验被覆盖的文件,默认模式 |
all | 同步后校验源目录里的所有普通文件 |
changed 是一个不错的默认平衡点:新文件直接复制,已有文件覆盖后重点确认。需要更强确认时再上 --verify all。
六、常用命令组合
1. 安全备份照片目录
先预览:
fastsync -n --strict ./photos /mnt/backup/photos
确认后执行:
fastsync --strict ./photos /mnt/backup/photos
这里用 --strict 是因为照片属于“丢了很麻烦”的数据,宁愿多算一点哈希。
2. 把构建产物镜像到发布目录
fastsync -n -d ./dist ./release
fastsync -d ./dist ./release
发布目录通常应该跟构建产物完全一致,所以这里会用 --delete 删除陈旧文件。
3. 限制并发线程数
fastsync -t 4 ./source ./target
-t / --threads 可以限制 worker 数量。大目录同步时,如果你不想把机械硬盘、移动硬盘或 NAS 打满,可以手动压一下并发。
4. 给脚本输出 JSON
fastsync -o json ./source ./target
文本输出适合人看,JSON 输出适合 CI、备份脚本、定时任务消费。FastSync 的进度和日志会走 stderr,摘要和 JSON 保持在 stdout,这样脚本读取 stdout 时不会被进度条污染。
5. 只看帮助
fastsync --help
fastsync share --help
fastsync connect --help
不带任何参数运行 fastsync 也会输出帮助。
七、一次性网络同步:share 和 connect
FastSync 还内置了网络同步,适合临时交付一个目录。
它的交互模型非常克制:共享方运行 share,FastSync 打印一次性验证码;连接方运行 connect,输入地址和验证码;同步完成后,共享方退出。
把目录发给别人
共享方:
fastsync s ./photos
s 是 share 的短写。启动后,FastSync 会打印一个验证码,比如 123456。
接收方:
fastsync c server.example.com ./photos -c 123456
c 是 connect 的短写。默认方向是 pull,也就是从共享方下载到本地目录。
让别人上传目录给你
如果你想临时收一个目录,可以让共享方以接收模式启动:
fastsync s ./inbox -r
上传方执行:
fastsync c server.example.com ./project -u -c 123456
这里 -u 表示 push,把本地 ./project 上传到共享方的 ./inbox。
默认情况下,上传方不能删除共享方已有文件。真的要允许上传端删除陈旧文件,需要共享方显式加 --allow-delete / -a,上传方也显式加 --delete:
fastsync s ./inbox -r -a
fastsync c server.example.com ./project -u -d -c 123456
这个设计挺重要:网络同步里,删除权限必须由接收删除影响的一侧主动放开。
网络同步需要记住的边界
| 点 | 说明 |
|---|---|
| 它是单向同步 | 每次选择下载或上传,不做双向合并 |
| 验证码一次性使用 | 适合短会话,不适合长期后台服务 |
| 默认成功一次即退出 | 传完就收口,减少暴露面 |
| 删除始终显式开启 | 不会默认删除接收方额外文件 |
| 传输基于 QUIC | 使用临时自签名证书和一次性验证码 |
| 接收文件会校验 | 使用 BLAKE3 校验,并通过临时文件替换目标文件 |
所以它很适合“我现在把这个目录发你一下”,或者“你把项目打包上传到我这里”。它不是常驻网盘,也不是冲突合并系统。
八、权限、时间和元数据
FastSync 会把“内容比较”和“元数据同步”拆开。
默认情况下,同名文件即使内容一致,也可以同步源端元数据,比如修改时间。你可以用这些参数调整:
fastsync --no-sync-metadata ./source ./target
fastsync --preserve-times false ./source ./target
fastsync --preserve-permissions true ./source ./target
常见选项:
| 参数 | 作用 |
|---|---|
--no-sync-metadata | 不单独同步内容已相同文件的元数据 |
--preserve-times <auto|true|false> | 是否保留源文件修改时间 |
--preserve-permissions <auto|true|false> | 是否保留源文件权限位 |
-p / --perms | 网络同步里保留权限位的快捷写法 |
权限位在跨平台同步时尤其要小心。Linux 到 Linux 可能很自然,Windows、macOS、Linux 混合时,权限语义并不完全一致。拿不准时,先用默认值。
九、我会怎么选参数
如果只是日常使用,不需要背完整命令表。记住这几组就够了:
| 目标 | 命令 |
|---|---|
| 预览同步 | fastsync -n ./source ./target |
| 执行同步 | fastsync ./source ./target |
| 预览镜像删除 | fastsync -n -d ./source ./target |
| 执行镜像删除 | fastsync -d ./source ./target |
| 重要数据强比较 | fastsync --strict ./source ./target |
| 全量复制后校验 | fastsync --verify all ./source ./target |
| 限制并发 | fastsync -t 4 ./source ./target |
| JSON 输出 | fastsync -o json ./source ./target |
| 临时共享目录 | fastsync s ./source |
| 接收共享目录 | fastsync c host ./target -c 123456 |
我的默认心智模型是:
先
-n看计划;涉及删除就-n -d;重要数据加--strict;脚本集成用-o json。
FastSync 最舒服的地方,不是参数多,而是危险动作都需要你明确说出口。速度是工具的锋利度,预览、校验和默认不删除才是它真正让人敢用的部分。

