理解 Everything 为什么快,需要先理解 NTFS 卷上文件元数据的存储方式。
NTFS 格式化时,会在卷上创建 $MFT(Master File Table)文件。它本质上是一个固定大小记录的数组——默认每条 1024 字节。每个文件和目录在 MFT 中占一条记录,记录号(MFT Entry Number)就是该文件在文件系统中的「身份证号」。
一条 MFT 记录包含多个属性(Attribute):$STANDARD_INFORMATION(时间戳、权限标志)、$FILE_NAME(文件名,可以有多个——长文件名和 8.3 短名各一条)、$DATA(文件内容或 resident 数据)。目录的 $INDEX_ROOT 和 $INDEX_ALLOCATION 属性存储 B-tree 索引,指向子文件的 MFT 记录号。
Everything 的核心操作:以 raw read 方式顺序读取 $MFT 的全部记录,提取 $FILE_NAME 属性中的文件名和父目录引用,在内存中构建完整的 path → filename 映射。这个过程是 O(n) 顺序 I/O,n 是文件总数——120 万文件在 NVMe 上通常 2-5 秒完成。
首次索引完成后,如果每次文件变更都重新读一遍 MFT,那就失去了速度优势。NTFS 提供了 USN(Update Sequence Number)Journal——一个固定大小的循环日志,记录卷上所有文件系统变更:FILE_CREATE、FILE_DELETE、RENAME_OLD_NAME、RENAME_NEW_NAME、DATA_EXTEND 等。
Everything Service 打开 USN Journal 句柄后,阻塞读取新记录。收到 RENAME 事件时,更新内存索引中对应条目的路径;收到 CREATE 时插入新条目;收到 DELETE 时标记删除。延迟通常在 100 ms 以内——你刚保存的文件,Everything 里几乎立刻能搜到。
voidtools 没有公开内部数据结构,但从 SDK 行为和内存占用可以推断:文件名被拆分为小写 token(支持 case-insensitive 搜索),存入 trie 或 B-tree。查询 config 时,从根节点匹配 prefix "config",返回所有匹配的完整路径。
120 万文件的内存占用约 47 MB(实测),折合 ~40 字节/条目。对比 Windows Search 的 Windows.edb 文件动辄 2-5 GB——因为 Windows Search 还索引文件内容、邮件、Outlook 项,并使用 ESENT 数据库引擎。Everything 只做文件名,数据结构可以极度精简。
读取 $MFT 需要 SeBackupPrivilege(备份权限),普通用户默认没有。因此 Everything 安装时会请求管理员权限,或者安装为 Windows 服务(以 SYSTEM 运行)。服务模式下,普通用户启动 UI 进程即可搜索,无需每次 UAC 提权。
注意:Everything 索引的是文件系统可见的所有文件名,不受 NTFS ACL 限制——即使用户没有某个目录的读取权限,仍然能在 Everything 里搜到该目录下的文件名。打开文件时才触发 ACL 检查。这在企业 DLP 场景需要注意。