fclones: 使用 Rust 编写的高性能重复文件查找和清理工具

19次阅读
没有评论

共计 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:

  1. 扫描文件并应用选择过滤器,读取文件大小
  2. 按大小分组,移除只有一个成员的组
  3. 移除重复的 inode(同一物理文件通过不同路径访问的情况)
  4. 哈希文件头部数据块(前缀),按前缀哈希拆分组
  5. 哈希文件尾部数据块(后缀),进一步拆分组
  6. 完整文件哈希,最终确定真正的重复文件
  7. 生成报告

这种多阶段方式意味着大多数文件在早期阶段就被排除(仅凭文件大小),只有真正可疑的候选文件才会进行完整哈希计算。

支持的哈希函数(通过 --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 是一个值得信赖的选择。

相关链接

正文完
 0
评论(没有评论)