FindLinks 学习笔记(12.4):NTFS 硬链接扫描与文件“多重身份”排查

适用人群:

需要做 磁盘清理 / 空间排查 / 安全取证 / 运维梳理 的同学,尤其是:

  • 想确认"这个大文件到底是不是被别的地方也引用了?"
  • 删除某个路径前,想知道"删了会不会影响其他应用?"
  • 想搞懂 NTFS 硬链接到底长什么样,怎么查、怎么用。

这一篇你可以收获:

  • 搞清楚 硬链接 的真实含义(不是快捷方式!)
  • 理解 Windows 下"一个文件多个路径"的机制
  • 会用 FindLinks 查某个文件 / 整个目录的硬链接情况
  • 知道在清理空间、排查问题时如何安全地对待硬链接文件

一、硬链接到底是个啥?别把它当快捷方式

在 NTFS 里,一个文件分成两个层次来理解:

  1. 数据本体:磁盘上的数据块 + 元数据(MFT 记录)
  2. 名字/路径 :目录里那一行 "文件名 → 指向某个 MFT 记录"

硬链接(Hard Link)= 给同一份数据,在不同目录下挂多个"名字"。

特点:

  • 多个路径指向 同一个 MFT 记录,数据完全相同、共享内容
  • 删除其中一个路径,只是删掉一个"名字",只要还有其他硬链接存在,数据就不会被真正删除
  • 只有最后一个硬链接被删掉,数据才会真正从磁盘上消失

和常见概念对比一下:

概念 存在层级 是否共享底层数据 是否依赖原路径存在
硬链接 文件系统/MFT ✅ 是 ❌ 不依赖
快捷方式 .lnk 普通文件 + Shell ❌ 否(只是指路牌) ✅ 是(路径变就废)
符号链接 重解析点 + 路径 视目标而定 ✅ 强依赖路径

所以:硬链接是"多马甲",不是"指路牌"。


二、为什么需要 FindLinks?

问题是:资源管理器看不出来谁是硬链接。

对你来说:

  • C:\logs\app.log
  • D:\backup\app.log

看上去是两份文件,大小都 1GB。

但实际上,它们可能只是同一个底层 MFT 记录的两个名字。

这会带来两个典型风险:

  • 误以为磁盘被两个 1GB 文件占满,其实只有 1GB
  • 在"错误"的路径上删除文件,以为还留了一份备份,结果其实全没了

所以我们需要一个能直接问 NTFS 的工具:

"这玩意儿到底有几个硬链接?它们都在哪儿?"

FindLinks 就干这个活。


FindLinks.exe 的命令行非常简单,常用就两种模式:

  1. 查询单个文件的硬链接情况
  2. 递归扫描某个目录下所有文件的硬链接

基础语法:

bash 复制代码
# 查询指定文件的硬链接
findlinks <文件路径>

# 递归扫描目录
findlinks -s <目录路径>

Tip:FindLinks 是 Sysinternals 工具,建议和其它工具放在统一目录,例如 C:\Tools\Sysinternals,加到 PATH 里。


四、查看单个文件的"多重身份"

先看最常用的场景:检查某个文件是不是硬链接的一员

示例:

bash 复制代码
findlinks C:\logs\app.log

典型输出(示意):

text 复制代码
FindLinks v1.xx - Locate file hard links
Sysinternals - www.sysinternals.com

Index: 0x0000000000012345
File: C:\logs\app.log
Links: 2

  C:\logs\app.log
  D:\backup\app.log

重点信息解读:

  • Index:底层 MFT 记录号,所有硬链接共享的"身份证"
  • Links: 2:说明这个文件有两个硬链接
  • 下面逐行列出所有路径(这就是"多重身份"的全名单)

经验规则:

  • Links = 1 → 这就是"单身文件"
  • Links > 1 → 这是"共享文件",删除时就要格外小心

五、递归扫描目录:找到"看着很多其实只有一份"的文件

在空间排查 / 取证场景里,你通常会想知道:

某个目录树下有哪些文件,其实是共享同一份数据的?

可以用 -s 递归扫描。

bash 复制代码
findlinks -s D:\Data

输出会罗列每个文件的:

  • MFT 索引
  • 硬链接总数
  • 当前路径
  • 如有多个硬链接则列出所有路径

如果想重点关注 Links > 1 的文件,可以结合 findstr 做粗筛:

bat 复制代码
findlinks -s D:\Data | findstr /C:"Links: " /C:"Index:"

或者导出到文件,后面用脚本处理:

bat 复制代码
findlinks -s D:\Data > D:\reports\findlinks_D_Data.txt

适合用来做"文件去重/异常排查"的底层数据来源。


六、硬链接在系统中的真实用法(顺便帮你"逆向理解"Windows)

一些典型用法:

1)系统组件/补丁共享

很多系统文件(特别是 WinSxS、组件存储相关)会通过硬链接机制:

  • 保持只有一份真正的数据
  • 在不同目录结构下呈现为"多份"

这就是为什么:

  • 你在资源管理器中看到一堆巨大的 DLL
  • 但实际磁盘空间没有被这么多倍占用

用 FindLinks 去看这些文件,你会看到大量 Links > 1 的情况。

2)杀毒/安全软件的"文件快照"

有的安全产品会利用硬链接:

  • 让一份数据暴露为多个快照路径
  • 或者在清理/还原时确保数据一致性

如果你在某些安全目录下看到奇怪的重复文件,FindLinks 能帮你确认它们是不是只是 "多马甲"。

3)你的脚本/备份策略可能"无意中"创建硬链接

例如用某些支持硬链接复制的工具(robocopy /B /COPYALL + 特定选项),

或者用 fsutil hardlink create 手动玩过硬链接,

FindLinks 就是之后"回头看你到底造了什么结构"的好帮手。


七、清理空间前,先查硬链接(避免"我以为有备份")

真实世界中很常见的翻车故事:

"我在 D:\backup\xxx.dat 上删文件,以为只是删备份,

结果生产目录 C:\app\data\xxx.dat 也没了......"

如果这两个路径是同一个硬链接集的一员,那么删掉其中任何一个最后一个链接

数据就会真正被删掉,任何一方都不能幸免。

一个比较稳妥的流程:

  1. 先用 FindLinks 查一下这个文件

    bash 复制代码
    findlinks D:\backup\xxx.dat
  2. Links: 数:

    • 如果 Links: 1:正常删除即可
    • 如果 Links: N (>1)
      • 把下方列出的所有路径记下来
      • 确认这些路径中,哪些才是你真正想保留/删除的
      • 再按计划逐个删除或保留
  3. 在批量空间清理脚本中,可以插入硬链接检查逻辑,避免"顺手一删,全删没了"的悲剧。


八、常见注意事项与坑点

1)硬链接只在 NTFS 上有效

  • FAT32 / exFAT 上没有硬链接概念

  • 跨卷(如 C: → D:)也不能创建硬链接

    但是可以通过 junction / symlink 在路径上跨卷,那是另一种机制(上一篇 12.3 讲过)

FindLinks 也主要针对 NTFS 文件系统。

  • 目录级重定向(junction / symlink / mount point)之前已经有 Junction 工具
  • FindLinks 专注"文件多马甲"的硬链接场景
  • 两者结合使用,能对整个路径结构做一个更全面的视图

3)备份/复制工具对硬链接的处理各不相同

有的:

  • 会把每个硬链接路径当成一个完整文件复制 → 体积直线上升
    有的:
  • 会保留硬链接语义 → 目的端仍是一份数据多个名字

在做迁移时:

  • 最好结合 FindLinks + 备份工具文档,确认"迁移后硬链接是否仍然存在"
  • 对关键系统目录,尽量不要自己"手搓硬链接结构"去改,除非非常清楚原理

九、命令片段小仓库(可以直接拿去用)

1)检查某个疑似"重复大文件"是不是硬链接

bat 复制代码
@echo off
set FILE=%1
if "%FILE%"=="" (
  echo 用法: checklink.bat ^<文件路径^>
  exit /b 1
)

echo [*] 正在检查硬链接: %FILE%
findlinks "%FILE%"

调用:

bat 复制代码
checklink.bat D:\bigdata\dump.bak

2)扫描一个目录下所有"多重身份文件"

bat 复制代码
@echo off
set ROOT=D:\Data
set REPORT=D:\reports\findlinks_multi.txt

echo 正在扫描 %ROOT% 下的硬链接文件...
findlinks -s "%ROOT%" > "%REPORT%"

echo 扫描完成,结果已保存到:
echo   %REPORT%
echo 建议后续用记事本 / VS Code 打开,搜索 "Links: " 并关注 Links > 1 的记录。

一句话定位:

FindLinks = "谁和谁共用一份身体"的真相检测器。

在这些场景尤其好用:

  • 做磁盘空间排查时,想确认"大文件到底是几份还是一份"
  • 清理旧目录时,担心误删掉实际上正在被别处使用的数据
  • 逆向理解 WinSxS / 系统组件存储的底层结构
  • 分析某些安全/备份软件创建的奇怪"重复文件"

配合上一节的 Junction、后面的 DU(磁盘空间统计)、PendMoves/MoveFile(重启后文件操作),

你就有了一套针对"文件系统怪现象"的侦探工具组合:

  • FindLinks:谁共享同一数据
  • Junction:哪几个目录其实是同一块区域
  • DU:哪里真正在占空间
  • PendMoves/MoveFile:不好动的文件,重启后按计划挪

下一篇我们就轮到 DU(Disk Usage):

把"感觉上很大"变成"数字上说话",帮你一眼锁定真正的大头空间杀手。

相关推荐
程序员大辉2 小时前
新人学习Flutter,如何搭建开发环境(附所有安装包)
学习·flutter
QT 小鲜肉2 小时前
【Linux命令大全】001.文件管理之diff命令(实操篇)
linux·运维·chrome·笔记
Ahtacca2 小时前
保姆级教程:Obsidian + PicGo + Gitee 搭建免费稳定的自动化图床
运维·笔记·学习·gitee·自动化
苦 涩2 小时前
考研408笔记之计算机组成原理(二)——数据的表示和运算
笔记·计算机组成原理·考研408
ZHang......2 小时前
synchronized(三)
开发语言·笔记·juc
檀越剑指大厂2 小时前
【Idea系列】换行处理
java·ide·intellij-idea
我的xiaodoujiao3 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 35--二次封装MySQL数据库连接操作
python·学习·测试工具·pytest
inputA3 小时前
【rt-thread】点灯实验和按键输入实验
c语言·笔记·学习·实时操作系统
Radan小哥3 小时前
Docker学习笔记—day013
笔记·学习·docker