共计 3083 个字符,预计需要花费 8 分钟才能阅读完成。
什么是 fclones
fclones 是一个使用 [[Rust]] 编写的命令行重复文件查找和清理工具。由 Piotr Kolaczkowski 开发,最初是一个 Rust 编程练习项目,后来演变为功能丰富、性能出色的生产级工具。fclones 采用 MIT 许可证发布,在 GitHub 上拥有约 2700 颗星。
fclones 的核心优势在于其多阶段渐进式过滤算法,能够在扫描过程中尽早淘汰非重复文件,大幅减少不必要的磁盘 I/O 操作。在 SSD 存储场景下,fclones 的速度通常是同类工具的 2-5 倍。
核心功能
fclones 提供了两大类功能:查找重复文件和处理重复文件。
查找功能:
- 查找重复文件、唯一文件、拥有 N 个以上副本的文件、副本不足的文件
- 支持多个目录根路径同时扫描
- 支持递归和非递归扫描,可设置深度限制
- 通过 glob 和正则表达式过滤文件
- 按文件大小过滤
- 正确处理符号链接和硬链接
- 支持从 stdin 读取文件列表
处理功能:
- 删除重复文件
- 移动重复文件到指定目录
- 将重复文件替换为硬链接或软链接
- 支持 reflink(写时复制)去重,适用于 [[Btrfs]]、XFS、APFS 等文件系统
- 基于时间戳或嵌套深度的优先级选择
- 干运行模式(dry-run)确保安全
输出格式支持标准文本、fdupes 兼容格式、CSV 和 JSON。
工作原理
fclones 使用一个七阶段的渐进式过滤管道来最大限度减少磁盘 I/O:
- 扫描文件并应用选择过滤器,读取文件大小
- 按大小分组,移除只有一个成员的组
- 移除重复的 inode(同一物理文件通过不同路径访问的情况)
- 哈希文件头部数据块(前缀),按前缀哈希拆分组
- 哈希文件尾部数据块(后缀),进一步拆分组
- 完整文件哈希,最终确定真正的重复文件
- 生成报告
这种多阶段方式意味着大多数文件在早期阶段就被排除(仅凭文件大小),只有真正可疑的候选文件才会进行完整哈希计算。
支持的哈希函数(通过 --hash-fn 选择):
| 函数 | 位宽 | 类型 |
|---|---|---|
| metro | 128-bit | 非加密 |
| xxhash3 | 128-bit | 非加密 |
| blake3 | 256-bit | 加密 |
| sha256 | 256-bit | 加密 |
| sha512 | 512-bit | 加密 |
| sha3-256 | 256-bit | 加密 |
| sha3-512 | 512-bit | 加密 |
默认使用 metro(最快)。除非从高速 SSD 或缓存数据中读取,否则非加密和加密哈希的差异很小。
性能优化策略:
- 为每个存储设备创建独立的线程池并自动调优
- 自动检测 SSD 和 HDD,调整并行度和缓冲区大小
- 在 HDD 上按物理数据位置排序文件操作
- 路径前缀压缩,处理百万级文件时节省内存
- 缓存友好的 I/O 模式
- 可选的持久化哈希缓存(
--cache标志),哈希以 inode 为键,文件重命名或移动不会使缓存失效
安装方法
[[Homebrew]](macOS/Linux):
brew install fclones
Snap(Linux):
snap install fclones
Cargo(从源码编译):
cargo install fclones
MacPorts(macOS):
sudo port install fclones
其他发行版:Arch Linux(AUR)、Alpine Linux、NixOS、Guix、openSUSE PackageHub 均提供包。
也可以从 GitHub Releases 页面下载预编译二进制文件。
生成 shell 补全脚本:
fclones complete bash # 或 zsh, fish, elvish, powershell
使用方法
fclones 的工作流程分为两步:先用 group 命令查找重复文件,再用操作命令处理。
查找当前目录下的重复文件:
fclones group /path/to/dir
仅扫描当前目录,不递归:
fclones group . --depth 1
查找唯一文件(没有重复的文件):
fclones group . --unique
查找副本不足 3 个的文件:
fclones group . --rf-under 3
保存结果到文件,然后分步操作:
fclones group /path/to/dir > dupes.txt
fclones remove < dupes.txt --dry-run # 先预览
fclones remove < dupes.txt # 确认后删除
管道操作,保留最新文件:
fclones group . | fclones remove --priority newest
将重复文件替换为硬链接:
fclones group . | fclones link
将重复文件替换为软链接:
fclones group . | fclones link --soft
使用 reflink 去重(需要支持的文件系统):
fclones group . | fclones dedupe
仅扫描特定类型的文件:
fclones group . --name '*.jpg' -i
使用哈希缓存加速重复扫描:
fclones group . --cache
输出 JSON 格式:
fclones group . -f json
对比分析
与主流重复文件查找工具的性能对比(来自 fclones 项目基准测试):
| 工具 | 语言 | 耗时 | 内存 |
|---|---|---|---|
| fclones | Rust | 0:34 | 266 MB |
| yadf | Rust | 0:59 | 329 MB |
| [[czkawka]] | Rust | 2:09 | 1.4 GB |
| rmlint | C/Python | 2:28 | 942 MB |
| jdupes | C | 5:01 | 332 MB |
| fdupes | C | 5:46 | 342 MB |
| rdfind | C++ | 5:53 | 496 MB |
| dupeguru | Python | 7:49 | 1.4 GB |
来自独立基准测试(Jyri Virkki 2022,约 15.4 万个真实文件):
SSD 冷缓存场景:fclones 约 10 秒,rmlint 约 17 秒,rdfind 约 28 秒,jdupes 约 32 秒。
HDD 冷缓存场景:rmlint 约 90 秒,rdfind 约 92 秒,fclones 约 124 秒,jdupes 约 269 秒。
功能对比:
| 特性 | fclones | rmlint | jdupes | fdupes | rdfind |
|---|---|---|---|---|---|
| 多线程 | 支持 | 支持 | 不支持 | 不支持 | 不支持 |
| SSD/HDD 自动调优 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| Reflink 去重 | 支持 | 不支持 | 支持 | 不支持 | 不支持 |
| JSON 输出 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
| 哈希缓存 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| GUI 可用 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| 预处理转换 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
总结来说,fclones 在 SSD 场景下性能优势明显,功能最为全面。在 HDD 场景下,rmlint 由于不同的 I/O 策略可以与 fclones 竞争。对于大规模多线程工作负载,fclones 是当前最好的选择。
适用场景
- 清理大量照片或媒体文件中的重复项
- NAS 或备份磁盘的去重
- 合并多个备份副本后清理冗余文件
- 在 [[Btrfs]] 或 APFS 文件系统上使用 reflink 节省空间
- CI/CD 管道中检查重复资源
- 配合 [[cron]] 定期扫描特定目录
GUI 版本
fclones 还提供了一个独立的 GUI 版本 fclones-gui,适合不习惯命令行的用户。GUI 版本提供了可视化的重复文件浏览和操作界面。项目地址为 https://github.com/pkolaczk/fclones-gui。
总结
fclones 是目前性能最好的重复文件查找工具之一,特别是在 SSD 存储环境下。其七阶段渐进式过滤算法、自动存储设备检测和哈希缓存等特性使其在处理大规模文件集时具有明显优势。两步式的工作流程(先查找后处理)和 dry-run 模式保证了操作安全性。对于需要定期清理重复文件的用户,fclones 是一个值得信赖的选择。
相关链接
- fclones 文档和 README
- fclones GUI 版本
- crates.io 页面
- Duplicate Finder Performance 2022 独立基准测试
- Homebrew Formula

