磁盘满了要倒数据、目录路径变更后一堆程序失灵、想让某几个文件夹看起来像长在同一个盘里……这些问题只要在Windows环境下待过一段时间,基本都会撞上。我最早接触mklink是因为一个存储结构的设计失误:当时某个应用把数据写死在D盘某个路径下,但D盘很快就要被塞满,我又不能随便改程序配置。后来发现 Windows 自带了一个叫mklink的命令,能在不惊动任何上层程序的前提下,把一个物理目录虚拟成另一个路径,程序眼里它还在原地,实际数据早已被搬走。这篇文章就把我在这条路上踩过的坑、验证过的细节、还有权限和网络共享这几个最容易出问题的点,一次性整理清楚。
mklink创建的虚拟目录,在Windows资源管理器里看起来和普通文件夹没有区别,双击能进去,往里读写文件照常工作,但本质上你操作的是一个指向真实存储位置的“入口”。它能在本地硬盘上把目录映射来映射去,也能通过UNC路径指向共享文件夹或NAS上的位置。这比单纯的“快捷方式”要底层得多,程序根本不关心路径是不是一个实际存在的文件夹,所以兼容性非常好。但也正因为它太透明,一旦遇到权限、网络策略、安全软件扫描之类的情况,排查起来会比普通文件夹麻烦不少。
1. 三种链接的本质区别:目录联接、符号链接与硬链接
很多教程一上来就让你执行mklink /J或者mklink /D,但不解释为什么有这么多参数,也不说明选错了会有什么后果。这一节先把最核心的概念掰开揉碎。
1.1 它们都长什么样,底层各是什么
Windows 下mklink能创建三种对象:
- 目录联接(junction):用
/J参数创建,只能用于目录,不需要管理员权限。底层通过 NTFS 的 reparse point 实现,记录的是绝对路径。老一点的系统把这种叫“挂载点”,很多工具软件(比如早期的分区助手、备份工具)生成的就是这个东西。 - 符号链接(symbolic link):用
/D参数创建目录符号链接,不加参数直接mklink则创建文件符号链接。它同样基于 reparse point,但既可以指向本地路径,也可以指向UNC网络路径。创建符号链接在默认系统策略下需要管理员权限(除非开启了开发者模式)。 - 硬链接(hard link):用
/H参数创建,只适用于文件,不能用于目录。它不产生新的“入口对象”,而是直接在 NTFS 文件系统层面给同一个文件数据增加了另一个文件名记录,两者没有主次关系,删除任何一个名字都不会影响数据本身。
这三者的区别单看定义容易晕,我用一个生活化的类比来解释:目录联接像是给房间加了一扇新的门,打开门进去还是原来那个房间,但这扇门只存在于这栋楼里,写着房间的绝对地址;符号链接则像一张写着详细地址的便签,你拿着便签可以去任何一个地方,甚至跨城市(跨机器)找到目标;硬链接更像是同一个房间有两个完全一样的门牌号,物业记录里两个号都指向同一个物理房间,任何一个门牌都能进,撕掉一个号牌另一个依然有效。
1.2 一张表看懂选型
| 特性 | 目录联接(/J) | 符号链接(/D 或默认) | 硬链接(/H) |
|---|---|---|---|
| 适用对象 | 目录 | 目录或文件 | 仅文件 |
| 是否支持网络路径 | 不支持UNC目标 | 支持 | 不支持 |
| 创建是否需要管理员权限 | 仅本地路径时不需要 | 默认需要 | 不需要 |
| 是否跨卷/跨盘符 | 支持(仅限NTFS目标) | 支持 | 仅限同一NTFS卷 |
| 删除时是否影响源数据 | 不影响源目录 | 不影响源文件/目录 | 删除链接不影响源数据(数据还在另一个名字下) |
| 程序眼中的样子 | 普通文件夹入口 | 区分对象类型,个别程序会特殊处理 | 普通文件 |
实践里我 90% 的目录虚拟化场景用/J,因为它不需要管理员权限,行为又稳定。只有两种情况下会改用/D:一是目标路径在另一台机器的共享上,二是某些特定软件强制校验路径对象的真实类型,要求“链接”存在而不是“目录联接”。
1.3 一个常见误解:目录联接是不是快捷方式?
不是。快捷方式(.lnk文件)是给 Shell 界面用的,双击它时是 Explorer 帮你打开了目标,很多命令行程序、服务进程根本不知道去解析.lnk。而目录联接或符号链接对操作系统来说就是一个可解析的路径节点,cd进去、dir查看、程序以该路径为工作目录,全都直接可用。所以如果你要处理的是“程序硬编码路径”这类问题,快捷方式完全派不上用场,必须用这种NTFS层面的链接。
2. mklink 命令实战:参数选择与典型操作流程
理解了原理就该上手了。这一节我会把所有常用场景的命令、执行顺序、以及“做完之后应该看到什么”都写出来,方便直接照着敲。
2.1 从最简单的本地目录迁移开始
场景:某程序把数据写到C:\ProgramData\MyApp\Data,但这个目录越来越大,C盘撑不住,你想把数据放到D:\DataStore\MyAppData。
操作步骤:
:: 1. 停止占用该目录的相关服务(这一步经常被忽略) :: 2. 把原目录整体搬到目标位置 robocopy "C:\ProgramData\MyApp\Data" "D:\DataStore\MyAppData" /E /COPYALL /MOVE :: 3. 创建目录联接,让原路径能直接访问新位置 mklink /J "C:\ProgramData\MyApp\Data" "D:\DataStore\MyAppData"第2步里的/MOVE会在复制完成后删除源目录,注意它不是“移动完毕再删”,而是边复制边删除,所以如果你对传输完整性有顾虑,建议拆成两步:先robocopy复制(不带/MOVE),确认无误后再手动删除源目录,然后创建联接。如果用/MOVE后发现数据不完整,源已经删了就非常被动。
创建完成后验证一下:在 Explorer 里导航到原路径,能看到内容;再用命令行执行dir查看目录属性,<JUNCTION>字样说明联接生效。
2.2 文件硬链接的用法:多目录共享同一份配置
硬链接的典型价值在于:你想让多个路径下都存在同一份文件,但又不希望出现“一份数据复制了多份”的副作用。
:: 假设同一个配置文件需要在两个App目录下都存在,且修改任何一边都能同步 mklink /H "C:\AppA\conf\settings.ini" "D:\Shared\settings.ini" mklink /H "C:\AppB\conf\settings.ini" "D:\Shared\settings.ini"之后你改D:\Shared\settings.ini,另外两个路径下的文件内容也会跟着变,因为底层是同一个文件数据。机器重启、进程切换都不影响这个关系。
但注意硬链接有个死限制:不能跨卷。也就是说源文件和链接必须在同一个盘符上,比如都在C盘或都在D盘。原因在于NTFS的硬链接在文件系统层记录的是文件引用(File Reference),而引用编号只在当前卷内有意义。如果尝试跨盘创建,会直接报“系统找不到指定的文件”或“拒绝访问”,很多第一次用的人会卡在这里。
2.3 没有管理员权限时怎么建符号链接
如果在公司环境登录的是普通域账号,没有管理员权限,mklink /D通常会提示“您没有足够的权限执行此操作”。此时有两个方案:
第一个方案:直接改用/J创建目录联接,它不需要管理员权限。这是最省事的,绝大多数目录虚拟化场景都能满足。
第二个方案:如果非要符号链接不可(比如要链接到一个网络共享路径),找管理员帮你调整本地策略:gpedit.msc→ 计算机配置 → Windows设置 → 安全设置 → 本地策略 → 用户权限分配 → 创建符号链接。对个人电脑来说,更方便的做法是打开“开发者模式”,路径是:设置 → 更新和安全 → 开发者选项 → 勾选“开发人员模式”。开启后,当前用户就可以创建符号链接而不需要提权的命令行窗口。这个方法我在某台用于开发的机器上实测有效,省去了每次右键“以管理员身份运行”的麻烦。
提示:无论如何,生产环境创建符号链接还是要遵循最小权限原则,别把这类权限随便授给普通用户,毕竟符号链接能指向UNC路径,如果配合不当可能成为信息暴露的通道。
3. 权限体系才是最大的坑:从管理员权限到所有权问题
链接创建好了,本地跑也没问题,但一旦涉及权限设置、写入失败、跨用户访问,很多诡异问题都冒出来了。这一节是我认为整篇文章里最值得反复看的部分。
3.1 为什么创建符号链接需要管理员权限,而目录联接不用
表面上这只是系统策略差异,底层逻辑其实是安全模型的设计。符号链接可以指向UNC网络路径,这就意味着:一个普通用户如果能在某个共享目录里创建符号链接并把链接指向另一个用户有权访问的敏感位置,那么其他用户点击这个链接时,就可能用自己的权限上下文去访问那个敏感位置,形成越权。而目录联接只能指向本地绝对路径,虽然也可能指向其他卷,但不会自动涉及“另一个凭据体系下的路径解析”。所以系统对符号链接严加看管。
理解这一点后,你就明白为什么“以管理员身份创建符号链接”只是第一步,真正出问题的是后续的访问权限。
3.2 创建链接之后,谁有权限往里写文件?
很多人以为链接就是一个“管道”,数据从管道流到目标文件夹,权限自然跟着目标文件夹走。这个理解大方向没错,细节上容易翻车。
当你通过C:\Public\DataLink(目录联接)访问D:\DataTarget时,操作系统在解析路径后,最终打开D:\DataTarget目录时使用的是D:\DataTarget自身的ACL(访问控制列表)。如果目录联接创建时没有任何额外设置,那么访问权限完全取决于目标目录的权限配置。
这个特性对“迁移并保留权限”有直接影响。比如原来在C:\OldPath下,某个用户对它有“修改”权限,你把目录搬到D:\NewPath后用 robocopy/COPYALL复制了权限,那么没问题;但如果当时搬家用的是普通复制(比如拖拽),目标目录继承了D:\NewPath父目录的权限,原来有权限的用户可能突然写不进去了。解决办法是重新设置目标目录的安全属性,或者用icacls把原权限导出再导入。
# 导出旧目录权限 icacls "C:\OldPath" /save "C:\acl_backup.txt" /t /c # 创建完联接后,把权限恢复到目标目录 icacls "D:\NewPath" /restore "C:\acl_backup.txt" /t /c3.3 链接本身是入口,还是目标目录的一部分?
这个问题很微妙。当你执行dir /q查看链接所在目录的属主时,看到的是链接本身的信息,还是目标目录的信息?答案是:对于目录联接,dir会显示目标目录的属主;对于符号链接,某些命令会解析并显示目标信息,但某些系统工具(比如备份工具)却会特殊处理符号链接对象本身。行为不完全一致。
这也意味着:如果你想知道“链接是否健康、目标是否还在”,不能只看 Explorer 的显示,最好用工具检查 reparse point 状态。Windows 自带的fsutil reparsepoint query可以查看链接指向的目标路径,适合快速验证。
3.4 所有权问题:为什么删不掉链接
遇到一种情况:目录链接创建成功了,但想删却提示“需要管理员权限”或者“找不到项目”。两个常见原因:
一是链接本身的所有权与当前登录用户不一致。创建链接时如果用了管理员权限,链接的属主是 Administrators 组,普通用户即使对目标目录完全控制,也无法删除这个入口对象本身。解决方法是重新获取所有权或用管理员命令行删除。
二是删除方式不对。删除目录联接和符号链接时,不要用资源管理器直接选中并按 Delete,更不要在链接路径后面加\*去删除内容——那会把目标目录的内容清空。目录联接的删除命令是rmdir(即使它看起来不是空目录),文件符号链接的删除命令是del。硬链接的删除跟普通文件的删除完全相同,只是它只会移除一个名称引用。
:: 删除目录联接/符号链接的正确姿势 rmdir "C:\VirtualDir" :: 删除文件符号链接 del "C:\VirtualFile.lnk"4. 实际使用场景拆解:目录聚合、程序路径兼容和数据迁移
原理说完,不落到真实场景里总感觉隔了一层。我把平时最常遇到的几类需求展开讲讲,每一步都对应到实际行动。
4.1 场景一:把分散在多个盘的目录聚合到一个“统一入口”
有些私有云盘软件、同步工具、笔记工具只允许你把存储根目录设在一个固定位置,或者你希望把所有项目的Data目录全部收拢到E:\AllData下面,但各个项目本身的目录结构又不能动。
做法是:在E:\AllData下面为每个项目创建一个子目录,然后把项目里的原始数据目录都迁移过去,再回到原位置创建目录联接。伪代码如下:
:: 为演示写清楚路径,实际请替换 mklink /J "D:\ProjectA\data" "E:\AllData\ProjectA\data" mklink /J "C:\Users\me\Documents\ProjectB\data" "E:\AllData\ProjectB\data"这样所有数据实际存储都在E:\AllData下,但每个项目访问自己的data目录时毫无感知。备份工具只需针对E:\AllData做一次集中备份,逻辑清晰不少。
4.2 场景二:程序“强行”指定安装目录时的兼容方案
有类程序很倔,安装时把路径写死在注册表或配置里,比如C:\Program Files (x86)\SomeVendor\AppName,但你又希望程序文件装在D盘,省C盘空间。直接改注册表容易出各种兼容性问题,用目录联接则温和很多:
:: 先把整个安装目录搬到D盘 robocopy "C:\Program Files (x86)\SomeVendor\AppName" "D:\AppData\SomeVendor\AppName" /E /COPYALL /MOVE :: 再在原安装位置建联接 mklink /J "C:\Program Files (x86)\SomeVendor\AppName" "D:\AppData\SomeVendor\AppName"程序启动、更新、卸载时,都会通过原来的安装路径访问到D盘的实际文件。升级补丁在执行文件替换时也正常,因为替换操作本质是写入目标路径的目录项,联接的解析对API是透明的。唯一要留意的是:个别安装程序在卸载时会校验目录真实卷标或物理路径,如果校验失败会拒绝卸载。真遇到这种情况,先删掉目录联接,把文件复制回原位置,再执行卸载即可。
4.3 场景三:日志、临时文件虚拟化到内存盘或另一块SSD
如果某程序疯狂产生日志,你完全可以把日志目录指到一块独立的固态盘上,避免日志写入影响系统盘IO。
mklink /J "C:\App\logs" "D:\FastSSD\AppLogs"这里有个潜在的连续性隐患:如果 D 盘在系统启动时挂载较慢(比如外接硬盘),而程序启动又早于挂载完成,链接会暂时显示为“不可用”,程序可能直接报错。所以我建议这类系统盘之外的联接目标,尽量放在系统能够保证顺序识别的固定盘或本地NVMe盘上,不要挂到容易掉线的USB移动硬盘上。
5. 网络共享下的虚拟目录:UNC路径、凭据与访问策略
网络共享是 mklink 最容易出难题的重灾区。甭管是文件服务器是Windows还是NAS,把目录联接指向一个共享路径后,各种权限符号、访问报错都来了。
5.1 谁在访问联接时负责认证?
一个常见的疑问:我用mklink /D把Z:\DataLink链接到\\192.168.1.10\share\public\data,然后同事访问我这台机器上的Z:\DataLink,他到底用的是他的凭据还是我的凭据来访问共享?
答案取决于访问路径从哪边开始解析。同事访问\\mycomputer\Z$\DataLink时,路径解析发生在我这台机器上,那么访问\\192.168.1.10\share\...时,发起认证的是我的机器服务账户(通常是SYSTEM或以共享配置的账户),而不是同事的身份。如果用的是符号链接且目标UNC路径需要特定账户,那么我这边必须提前建立好到目标共享的会话。在命令行里可以用net use维护这个会话。
但如果同事是直接 SSH/RDP 到我的机器上,然后在本机打开Z:\DataLink,此时会以他在我那台机器上的登录身份访问 UNC 路径,凭据就会变成他的。同一根链接,访问入口不同,结果完全不同,这点不搞清楚会排查到怀疑人生。
5.2 为什么符号链接指向UNC路径有时会自毁长城
当链接目标UNC路径对应的共享不可用时(比如服务器休眠、IP变了、共享被删除),符号链接本身并不会自动修复,你会在 Explorer 里看到一个“无法定位”的条目。而且某些安全软件在扫描时会因为链接指向不可达网络而删除链接本身,这点很坑。
针对这种情况,我的建议是:优先在网络驱动器映射层面做虚拟化,而不是在目录层面做。即先用net use Z: \\server\share映射出盘符,再创建指向Z:\某个子目录的目录联接。好处是网络断线后重新拨号,盘符映射恢复,目录联接跟着恢复,不用重建。而直接指向长UNC路径的符号链接一旦断链,恢复起来要主动重新创建,做不到自动化。
5.3 共享里的共享:对网络共享根目录或父目录是否可写
在共享上使用 mklink 创建链接的另一个坑是:如果目标共享的根目录不允许你写入 reparse point,那么创建会失败。特别是当你通过 UNC 路径直接执行mklink /D \\server\share\link \\server\share\realdata时,系统会提示访问被拒绝,哪怕你有“修改”权限,因为 NFS/共享层面的写入策略可能不允许在挂载根上创建特殊对象。
更稳妥的操作顺序是:在服务器本机创建好链接,然后把链接所在的目录整体共享出去;或者把链接建在本地,再通过本地机的共享暴露给其他机器。让客户端直接远程创建链接,十次里能成功三次就算运气好。
5.4 跨机器的相对路径陷阱
如果你把整个D:\DataRoot目录共享出去,其中某个子目录是指向D:\OtherLocation\data的联接,那别的机器访问时会看到什么?他们会看到D:\OtherLocation\data的内容,但前提是那个目标目录本身可被共享访问链覆盖。如果目标目录不在共享范围之外,客户端访问时会得到一个指向自己机器本地路径的错误解析——因为目录联接携带的目标路径是绝对路径,客户端会自动尝试解析自己机器上的那个绝对路径。这个问题几乎每个新手都会踩,因为它只有在跨机器访问时才暴露。
规避方式:尽量保证链接目标位于同一个共享树的内部,或者改用符号链接加相对路径(符号链接支持相对目标),或者干脆在服务器上把目标目录也纳入同一个共享根。
6. 链接的删除、管理与故障排查实用手册
前面提到删除方式,但链接的生命周期管理远不止删除一步。这一节我把日常运维需要的命令和判断思路全部列出来。
6.1 如何快速找出系统里所有链接
写个简单脚本扫描指定目录树下的 reparse point 对象:
# 递归查找指定目录下的所有链接类型对象 dir -Path "C:\" -Recurse -Force | Where-Object { $_.Attributes -match "ReparsePoint" } | Select-Object FullName, LinkType, Target当然全盘扫描会比较慢,建议指定到有可能存在链接的目录。也可以用工具的/L参数,许多命令行工具都支持列出链接对象本身。
6.2 链接损坏时怎么诊断
症状通常表现为三种:资源管理器里链接图标变成无法访问、dir时看到目录存在但打不开、程序写文件时抛出“目录不存在”。
排查顺序:
- 确认目标路径是否真实存在:进入资源管理器直接输入目标地址,或在命令行
dir目标路径。 - 确认访问权限:用
/J创建的目录联接,目标目录ACL是否有当前用户权限;如果是符号链接,还要额外确认“跳过遍历检查”权限是否缺失。 - 确认 reparse point 是否还在:
fsutil reparsepoint query查询该链接的状态。 - 确认是不是被杀毒软件清掉了:查安全软件的隔离记录。
我用一个表格总结常见现象与原因:
| 现象 | 最可能原因 | 对策 |
|---|---|---|
| 链接存在但打不开,提示“文件或目录损坏” | reparse point损坏或目标路径不可达 | 删除链接并重建 |
| 链接被系统自动删除 | 安全软件扫描后隔离了链接对象 | 在安全软件中加白名单 |
| 创建成功但重启后失效 | 目标盘挂载顺序问题或链接在注册表启动项之前被访问 | 手动验证,必要时改用开机脚本重建 |
| 从网络共享访问链接总是404 | 目标绝对路径在客户端被错误解析 | 改用共享树内的相对目标或调整共享范围 |
| 程序无法在链接目录下创建文件 | 目标目录ACL权限不足 | 用icacls修正目标目录权限 |
6.3 备份时如何正确对待链接
备份是另一个高频翻车点。如果你用robocopy备份一个包含目录联接的目录树,默认情况下 robocopy 会跟随链接并复制目标内容,这可能导致备份体积膨胀、甚至出现循环复制(如果链接目标又回溯到父目录)。稳妥的做法是在备份时跳过 reparse point,或者只备份链接对象本身:
:: 只复制链接对象而不跟随目标内容 robocopy src dst /E /COPYALL /XJ :: 注意:/XJ 含义是排除junction点,不进入目标目录如果是符号链接且希望保留链接属性而不是复制目标,不同备份工具的行为各异,最简单的验证方式:备份完再检查备份目录里是否出现了链接对象,没有就说明被跟踪复制了。针对目录迁移需求的备份,我建议先把链接按普通目录看待做全量,另做一份“链接清单”文件记录映射关系,恢复时先恢复普通目录,再根据清单重建链接,这样最可控。
7. 权限与网络共享的进阶避坑经验
最后再补充几个我实际中反复遇到的边界情况,这些在文档里不太容易被注意到,但真遇到了非常浪费时间。
7.1 不要在移动硬盘或U盘上创建目录联接
大部分U盘和移动硬盘默认文件系统是FAT32或exFAT,这两种文件系统根本不支持 reparse point。在它们上面运行mklink会直接报“文件系统不支持虚拟路径”。如果要让U盘支持,需要格式化为NTFS(右键格式化时选择文件系统为NTFS),但这也意味着U盘在部分播放器、车载系统上无法识别,所以除非确定使用场景,否则不建议为了一个联接牺牲兼容性。
7.2 符号链接的“相对目标”比想象中更实用
符号链接创建时可以指定相对路径作为目标,例如:
:: 目标路径写成相对路径,链接对象和目标可以作为一个整体整体搬移 mklink /D "D:\Project\link" "..\data"这里..\data相对于链接所在的目录解析,即实际指向D:\Project\data。好处是:你把这个Project目录整体拷到别的盘符或别的机器,链接和目标一起搬走后依然有效,不会出现绝对路径断链。
这个技巧在发布代码、同步项目时非常实用。比如一个项目里既有源码又有大型资源文件夹,你希望让某块逻辑看到的目录入口保持一致,同时又不想把大型资源复制进代码目录,用相对路径符号链接就能实现“可迁移的虚拟化”。
7.3 在 NTFS 权限模型里,链接本身是“被遍历对象”
Windows 访问检查对 reparse point 有一个额外要求:用户需要具备“遍历文件夹/执行文件”权限才能穿过链接。大多数情况下,普通用户是有的,但有些企业环境会收紧这个权限。症状是:用户能看到链接,能列出目录名,但进不去,错误提示是“拒绝访问”。如果你确定目标目录ACL没问题,就要去查“遍历检查”权限是否被拒绝。
另外注意:SMB共享上的符号链接默认在客户端是禁用的,即使用mklink /D创建成功了,通过共享访问时也可能因为共享端的SymlinkRemoteAccessCheck策略而无法穿透。遇到这种问题,建议在共享服务器本地验证链接是否正常,再决定是否调整共享策略。
7.4 链接命令的“隐藏提醒”:mklink 不接受相对路径的 /J
/J目录联接只接受绝对路径作为目标,这是一个硬性限制。你给mklink /J C:\link ..\data会报错,但mklink /D C:\link ..\data却正常,因为符号链接支持相对目标。如果非要用目录联接又想实现可迁移,唯一的办法是脚本动态获取当前路径再拼接绝对路径,稍显繁琐,但能换来较低权限要求和更高兼容性。
7.5 会不会有性能损耗
目录联接和符号链接本身在路径解析时会有微小的开销,但对最常用的文件打开、读写而言基本可以忽略不计。我在一台日常开发机上用目录联接聚合了三个项目的存储目录,持续运行了几个月,IO性能、IDE索引速度都没有可见差异。真正影响性能的是网络符号链接——如果链接目标是UNC路径,每次访问都要经过网络解析,这个延迟不是链接机制造成的,而是网络访问天然的开销,千万别把这笔账算在 mklink 头上。
8. 最后再说一个实际运维里的小技巧
用 mklink 管理虚拟目录时,最怕的就是时间一长忘了哪里建了链接、目标在哪。我个人的做法是:在所有虚拟目录的统一上级放一个_LINKS_README.md,记录每一条链接的创建时间、源路径、目标路径、创建命令和用途说明。别小看这一行笔记,半年之后你一定会回来感谢当时的自己。再配合计划任务每周自动检查一遍关键链接是否完好,日志里能直观看到哪条链接失效了,而不是等到用户报错才发现。
另外还有个小习惯:给重要的符号链接做完之后,立刻用fsutil reparsepoint query导出一条基线记录,发生意外时对照基线能快速确认是不是 reparse point 本身损坏了。我自己用过一次后就把这个步骤固定进了操作规范,有好几次安全软件误清链接都是靠它快速定位的。