ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows C盘清理:AppData\Local分级瘦身与目录联接搬迁

Windows C盘清理:AppData\Local分级瘦身与目录联接搬迁

系统盘飘红这事,几乎每个长期用 Windows 的人都撞上过。任务栏右下角弹出"存储空间不足",打开资源管理器一看,C 盘只剩个零头,于是开始满世界找"Windows C盘清理"的教程,翻了一圈发现十个帖子里八个让你删 Temp、删休眠文件,然后就没下文了。真正占地方的那位——C:\Users\<你的用户名>\AppData\Local——往往被一句"隐藏文件夹,慎动"轻轻带过。这篇就把 Local 文件夹拆开讲透:它里面每一类目录到底装了什么、哪一坨可以放心瘦身、哪一坨动了要重装软件、搬迁大目录的目录联接怎么做、以及"安全删除"这条线在哪里。内容偏实操,适合被 C 盘折磨过的普通用户,也适合需要在一堆开发工具和容器镜像之间腾挪空间的开发者,看完你至少能自己判断"这个目录我能不能删",而不是靠猜。

1. 先把 AppData\Local 的底细摸清楚,再谈删

1.1 一条默认隐藏、却吃掉半个系统盘的路径

AppData这个目录从 Vista 时代开始成为 Windows 用户配置的标准落地位置,路径固定为C:\Users\<用户名>\AppData,并且默认带隐藏属性。微软把它藏起来不是故弄玄虚,而是因为这个目录里既有可以随手清掉的缓存,也有删掉就会丢配置、丢登录态、丢授权信息的关键数据,混在一起,普通用户根本分不清。结果就是两个极端:要么完全不敢碰,眼睁睁看着它从几个 G 涨到几十个 G;要么听了某篇"暴力清理"教程,把整个 Local 目录清空,然后发现浏览器要重新登录、开发环境要重新拉依赖、某些软件直接打不开。

我见过最典型的一台机器,256G 的系统盘只剩 2.8G 可用,用工具一扫,AppData\Local独占 71G。其中聊天工具的图片视频缓存 18G,某个 Chromium 内核浏览器的 Cache 加 Code Cache 9G,包管理器缓存 12G,容器平台的虚拟磁盘 26G,剩下的是各种零碎。这些数字说明一件事:Local 不是"临时垃圾场",而是绝大多数现代应用的事实上的数据落盘区,你不去管它,它只会越来越大,因为几乎所有应用的设计前提都是"用户磁盘无限大"。

所以清理 Local 的正确姿势不是"删",而是"分类 + 定向处理"。先建立一张地图,知道哪条路通向哪里,再决定是清空、是搬迁、还是原封不动。

1.2 Local、LocalLow、Roaming 三兄弟,删错门派要出事

AppData下面有三个子目录,名字很像,作用完全不同。很多人清理时把三者混为一谈,这是最容易出事的地方。

目录数据性质是否随账户漫游典型内容删空的后果
Roaming用户配置、偏好设置是(域环境或账户同步时会跟随)软件配置文件、界面布局、账号配置软件恢复默认设置,需要重新配置
Local本机专用数据、缓存、大型本地库否缓存、临时文件、本地数据库、虚拟磁盘、包管理器缓存大部分可重建,少数会丢本地数据
LocalLow低完整性级别进程的数据否受限权限进程(如部分浏览器渲染进程)写入的配置一般可重建,影响面小

关键区别在"是否漫游"。Roaming的设计意图是"换一台机器登录同一账户,配置跟着走",所以它里面不该放大文件;Local则是"只属于这台机器",应用可以放心地往里面塞几百兆的缓存和几个 G 的数据库。这就解释了一个常见现象:你在Roaming里往往只能看到几十兆的配置文件,而Local轻松几十个 G。

理解了这层设计,很多判断就顺了。看到Local下某个目录叫Cache、Temp、CrashDumps、GPUCache,基本可以判定是可再生的;看到Roaming下某个.ini、.json,那就是配置,别碰。清理的主战场在 Local,但 Local 内部也得分级,下一节就说这个。

1.3 三级分类法:随便删、谨慎删、碰都别碰

我把Local下的目录按风险分成三档,这套分类我用了好几年,基本没出过岔子。

第一档,随便删(可再生,删了应用自己会重建):各类Temp、Cache、Code Cache、GPUCache、ShaderCache、CrashDumps、Logs、logs、GPUCache、D3DSCache、缩略图缓存thumbcache_*.db、安装残留的临时解压目录。这类目录的共同特征是:名字里带 cache/temp/log/dump,删掉之后应用首次启动会稍微慢一点,然后一切如常。

第二档,谨慎删(需要先退出应用,删了会丢一部分本地状态但不致命):浏览器User Data\Default下的Cache、Service Worker\CacheStorage(清了要重新加载离线资源,网页登录态一般保留);聊天工具的图片视频缓存目录(删了历史消息里的老图会显示"文件已过期",重新点开可再下载);邮件客户端的离线缓存.ost(删了会重新从服务器同步,但离线期间的本地邮件没了);商店应用Packages\<包名>\LocalCache(只清 LocalCache 子目录,别动整个包目录)。

第三档,碰都别碰(删了要重装或重新授权):Packages下的整个包目录、浏览器User Data根目录(含书签、密码、扩展)、各类软件的授权与激活缓存、输入法用户词库、密码管理器本地库、证书与密钥目录、容器平台正在使用的虚拟磁盘文件。这一档的判断标准很简单:目录名里出现 License、Activation、Key、Vault、Profile、UserData(不带 Cache 后缀)、.db、.sqlite、.vhdx,一律先查清楚再动手。

这套分级不是死的,遇到拿不准的目录,最稳妥的办法是先改名加个.bak后缀,跑两天应用,没异常再删。多花两天时间,换的是不用重装系统的安心。

2. 动手前的准备:量体积、留退路、选工具

2.1 不装任何软件,先看清到底谁在吃盘

清理最忌讳上来就删。第一步永远是"量化"——知道每个子目录占多少,才能决定动谁。资源管理器里进入%LOCALAPPDATA%(地址栏直接敲这个变量,比一层层点快得多),右键属性能看到总量,但子目录要一个个点,几十个目录点下来人都麻了。

更快的办法是用 PowerShell 一条命令把所有子目录的体积排个序。按下 Win+X 选"终端"或"Windows PowerShell",粘贴下面这段:

$root = "$env:LOCALAPPDATA" Get-ChildItem -Path $root -Directory -Force -ErrorAction SilentlyContinue | ForEach-Object { $size = (Get-ChildItem -Path $_.FullName -Recurse -File -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum [PSCustomObject]@{ Name = $_.Name SizeGB = [math]::Round($size / 1GB, 2) LastWrite = $_.LastWriteTime.ToString("yyyy-MM-dd") } } | Sort-Object SizeGB -Descending | Select-Object -First 25 | Format-Table -AutoSize

这段脚本做了三件事:遍历 Local 下的直接子目录、递归累加文件大小、按 GB 降序取前 25 名,同时带出最后修改时间。最后修改时间这个字段很有用——三个月没动过的大目录,八成是可以清的历史残留;天天在变的,说明应用还在活跃使用,动它要考虑影响。

要是嫌命令慢(机械盘上递归统计几十万个文件确实慢),可以用图形化的磁盘占用分析工具,这类工具的原理都是直接读 NTFS 的 MFT 表,扫几十万文件只要十几秒,能直观看到"哪个目录是棵大树、树杈在哪"。选这类工具时注意一点:只装那种纯绿色、只读扫描的,别装带"一键优化""注册表清理"功能的,那类功能才是真正的风险源。

提示:统计时加-Force参数是为了把隐藏文件也算进去,不加的话很多缓存目录的隐藏文件会被漏掉,体积算出来严重偏小。

2.2 建一个还原点,再列一张"后悔药"清单

动手之前有两件事必须做,加起来不超过五分钟,但能救命。

第一件是创建系统还原点。按 Win+R 输入sysdm.cpl,切到"系统保护"选项卡,选中 C 盘,点"创建",起个名字比如before-c-clean。这里有个坑:很多人的 C 盘系统保护默认是关闭的,如果"保护设置"那一栏显示"关闭",先点"配置"启用,并分配 5% 到 10% 的空间。还原点不保护用户文件,但它能救回被误删的系统组件和注册表项,值这个空间。

第二件是列清单。在记事本里建一个表,三列:目录完整路径、当前体积、计划动作(清空/搬迁/保留)。这个动作看起来笨,但它的价值在后面——万一某个软件出了怪问题,你翻清单就知道自己动过什么,而不是靠回忆。我自己的清单里还会加一列"验证方式",比如"清完打开浏览器确认能正常加载网页""搬迁后启动一次应用确认不报错",把验证动作前置写下来,清理就不会变成一场盲盒。

还有一个细节:清空目录和删除目录是两回事。很多应用启动时会检查自己的缓存目录是否存在,不存在就重建,但也有少数应用会直接报错退出。所以稳妥做法是"清空内容、保留目录结构",而不是Remove-Item把整个目录端掉。命令行清空时可以保留顶层目录,只删里面的文件和子目录,这一点在脚本里要写清楚。

2.3 工具选型:命令行、图形界面、第三方清理软件怎么选

三种工具各有适用场景,混着用效率最高。

**图形界面(资源管理器)**适合处理少量、明确的大目录。优点是所见即所得,删之前能看一眼内容;缺点是遇到路径过长(超过 260 字符)或者权限受限的目录会卡住甚至报错,而且大批量操作时点击成本太高。

**命令行(PowerShell / 批处理)**适合重复性劳动和需要精确控制的场景。比如"清空 Temp 下所有 7 天前的文件"这种带条件的操作,图形界面根本做不了。命令行的另一个优势是可脚本化——写好一次,以后每次双击运行即可,这也是本文后面会给完整脚本的原因。

第三方"一键清理"工具我的态度比较保守。这类工具的问题不在于技术,而在于规则不透明:它替你决定删什么,你不知道它删了什么,出了事也无从排查。而且不少工具的清理规则偏激进,会把"缓存"和"用户数据"混为一谈。如果你确实想用,至少满足两个前提:一是能查看清理项明细并逐项勾选,二是第一次使用时先只勾选"临时文件"这一类,跑通没问题再扩大范围。

相比之下,Windows 自带的磁盘清理(cleanmgr)反而更值得信任,因为它的规则是系统自己定义的。它有个隐藏玩法:命令行执行cleanmgr /sageset:1会弹出一个超长的勾选列表,把你想清理的类别勾上并保存,之后用cleanmgr /sagerun:1就能按这套配置静默执行。这个组合适合做成计划任务,每月跑一次,处理系统更新残留、缩略图缓存这些常规项,省得每次手动点。

3. Local 文件夹瘦身实操:从通用缓存到专项大户

3.1 第一刀:Temp 与各类临时目录的正确开法

%LOCALAPPDATA%\Temp是清理的第一站,也是最安全的站。它的位置就是C:\Users\<用户名>\AppData\Local\Temp,环境变量%TEMP%和%TMP%默认都指向这里。所有程序运行时的临时解压、临时下载、临时日志都往这儿扔,而且绝大多数程序在退出时并不会主动清理,日积月累几个 G 很常见。

清理时直接Remove-Item整个目录会踩两个坑:一是目录里正在被运行中的程序占用的文件删不掉,会刷一屏红色错误;二是把 Temp 目录本身删了,某些老程序会找不到路径报错。正确写法是清空内容、保留目录,并忽略错误:

$temp = "$env:LOCALAPPDATA\Temp" Get-ChildItem -Path $temp -Force -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-1) } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue

这里加了"只删一天以前的"这个条件,是个经验值。为什么不删当天的?因为可能正有安装程序在使用临时目录,删了会导致安装失败,而且失败信息通常很隐晦,你会以为是安装包坏了,排查半天。留一天缓冲,成本几乎为零,风险小很多。

同一条线上还有几个值得顺手处理的:%LOCALAPPDATA%\CrashDumps(程序崩溃转储,单个文件可能几百兆,除非你在做故障分析,否则可以全清)、%LOCALAPPDATA%\Microsoft\Windows\Explorer\thumbcache_*.db(缩略图缓存,删了下次浏览图片会重新生成,会有短暂卡顿)、%LOCALAPPDATA%\D3DSCache(着色器缓存,删了游戏首次加载会重新编译,会慢一点但无副作用)。

注意:不要在系统刚启动、后台还在跑更新的时候清 Temp。这时候系统组件自己也在用临时目录,删到一半容易触发更新失败。挑一个应用都关掉、机器空闲的时间段做,成功率高一截。

3.2 第二刀:浏览器、聊天工具、办公套件的缓存定向清理

这三类是 Local 里最典型的"吞盘大户",而且清理逻辑各不相同。

Chromium 内核的浏览器结构高度相似,缓存基本都在%LOCALAPPDATA%\<厂商目录>\<产品目录>\User Data\Default\下面,重点关注四个子目录:Cache(网页资源缓存)、Code Cache(编译后的 JS 缓存)、GPUCache(GPU 渲染缓存)、Service Worker\CacheStorage(离线资源)。这四个加起来,重度使用者轻松 5 到 10 个 G。清理时必须先完全退出浏览器(注意检查托盘区和任务管理器,很多浏览器关窗口后仍有后台进程驻留),否则文件被占用删不掉。

这里最容易犯的错是把User Data整个目录删掉。那个目录里除了缓存,还有Bookmarks、Login Data、History、Preferences这些真正值钱的东西,删了等于浏览器恢复出厂设置,书签和保存的密码一起没。所以清理路径要精确到Default\Cache这一级,别往上多走一层。

聊天与协作工具的缓存通常在%LOCALAPPDATA%\<产品目录>\下的Image、Video、File、Cache之类的目录里,体积主要来自历史图片和视频。这类缓存的特殊之处在于它和消息记录绑定:删掉之后,聊天窗口里那些老图片会变成占位符或者"文件已过期",点一下能重新从服务器拉回来(前提是服务器还留着)。所以清理这类目录的实际影响是"历史媒体需要重新下载",功能上没损失,但如果你经常离线翻旧聊天记录,就得掂量一下。

更稳妥的做法是优先用应用自带的清理入口。现在主流聊天工具基本都在"设置 - 存储/通用 - 存储管理"里提供了按时间或按会话清理的选项,它比你直接删目录更懂自己的数据结构。我一般的顺序是:先用应用内清理,清完再看目录还剩多少,剩下的才是可以直接删的纯缓存。

办公套件这边要小心一点。邮件客户端的本地缓存文件(.ost)动辄几个 G,原理是把服务器上的邮件同步到本地以便离线访问。删掉它确实能立刻释放空间,重启客户端会重新同步,但同步过程视邮箱大小可能要几十分钟甚至几小时,而且离线期间本地独有的邮件(如果有)会一起没。所以这类文件我只建议在磁盘实在撑不住的时候动,且动之前确认邮箱是纯服务端存储模式。

3.3 第三刀:开发环境与虚拟化留下的占地

如果这台机器写过代码,Local里的大头多半在这儿。逐个说。

包管理器缓存是最容易回收的一块。Node 生态的缓存默认在%LOCALAPPDATA%\npm-cache,清理命令是npm cache clean --force;Python 生态的缓存在%LOCALAPPDATA%\pip\Cache,用pip cache purge清;.NET 生态用dotnet nuget locals all --clear一条命令搞定。这些缓存的作用是"下次装同一个包不用重新下载",删掉不影响已安装的项目,只是下次装依赖会慢一些。一个跑了两年项目的开发机,这几个加起来十几 G 很正常。

容器与虚拟化平台是另一个量级。以常见的基于 WSL 的容器方案为例,它的数据落在一个ext4.vhdx虚拟磁盘文件里,路径通常在%LOCALAPPDATA%\<平台目录>\下。这个文件的特点是只增不减——你在容器里删了镜像,vhdx 文件本身不会自动缩小,因为里面被释放的块变成了"空洞"。所以经常出现"镜像删了 20G,磁盘空间一点没回来"的情况。

处理办法分两步。先关停再压缩:

# 1. 关停相关服务,确保虚拟磁盘不被占用 wsl --shutdown # 2. 用 diskpart 压缩虚拟磁盘(需要管理员权限) @" select vdisk file="$env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx" attach vdisk readonly compact vdisk detach vdisk exit "@ | diskpart

compact vdisk的作用是回收虚拟磁盘里的空洞块,实测一个长期使用的 vhdx 压缩后体积能掉三到五成。补充一点,较新版本的 WSL 支持把发行版磁盘设为稀疏模式(wsl --manage <发行版名> --set-sparse true),开启后释放的空间会自动归还,省去手动压缩这一步,值得优先尝试。

IDE 与构建工具的本地缓存也别放过。构建工具的项目级缓存目录(各类.gradle、.m2、node_modules的全局缓存副本)往往散落在用户目录下,单个项目几十上百兆,几十个项目就是几个 G。Electron 系的应用(很多桌面客户端都是)每个在%LOCALAPPDATA%\<应用名>\下都有独立的缓存和旧版本残留,卸载重装几次就会留下好几份,这类"孤儿目录"可以通过对比已安装程序列表来识别。

3.4 把流程固化成脚本,以后每次双击就行

手工清一轮最多个把月又满,所以值得花二十分钟写个脚本。下面这个脚本是我自己在用的简化版,核心设计是白名单 + 试运行模式:只清理明确安全的目录,且第一次跑只打印不删除,确认无误再真正执行。

# C盘Local目录定向清理脚本(白名单模式) param( [switch]$Execute # 不加此参数时为试运行,只统计不删除 ) $targets = @( "$env:LOCALAPPDATA\Temp", "$env:LOCALAPPDATA\CrashDumps", "$env:LOCALAPPDATA\D3DSCache", "$env:LOCALAPPDATA\Microsoft\Windows\Explorer" ) $totalFreed = 0 foreach ($path in $targets) { if (-not (Test-Path $path)) { continue } $files = Get-ChildItem -Path $path -Recurse -File -Force -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-1) } $size = ($files | Measure-Object -Property Length -Sum).Sum if (-not $size) { $size = 0 } $totalFreed += $size Write-Host ("{0,-60} {1,8:N2} GB" -f $path, ($size / 1GB)) if ($Execute) { $files | Remove-Item -Force -ErrorAction SilentlyContinue } } if ($Execute) { Write-Host ("实际释放约 {0:N2} GB" -f ($totalFreed / 1GB)) } else { Write-Host ("预计可释放 {0:N2} GB,确认无误后加 -Execute 参数执行" -f ($totalFreed / 1GB)) }

用法是先进 PowerShell 执行.\clean-local.ps1,看输出列表里每一项预计能释放多少,确认这个目录确实该清,再执行.\clean-local.ps1 -Execute。白名单的好处是永不误伤——你只清理你明确列出来的目录,新增的目录不会因为"看着像缓存"就被自动干掉。

脚本里那个"一天以前"的条件可以按需调整。如果是长期没清过的机器,改成AddDays(-1)就够了;如果是想彻底清空,把条件去掉也行,但一定要先关闭所有应用。另外提醒一句,脚本执行时如果遇到权限拒绝的报错属于正常现象,那些被系统占用的文件本来就不该在这一轮被删,-ErrorAction SilentlyContinue会把它们跳过。

4. 搬盘而不是删盘:用目录联接把大目录挪走

4.1 mklink 的三种链接方式,选错了会白干

有些目录删不了也不能删,但确实占地方,比如某些必须在本地存在的数据库、容器虚拟磁盘、大型离线资源。这种时候正确做法不是删,而是"搬走但让程序以为还在原地"。Windows 提供三种链接方式,行为差别很大。

方式命令参数跨卷支持是否需要管理员目标删除后的表现适用场景
目录联接/J支持(NTFS)不需要访问时报路径不存在绝大多数搬目录场景
目录符号链接/D支持需要(或开发者模式)变成悬空链接需要链接到网络路径时
硬链接/H不支持(必须同卷)不需要数据仍可访问单个文件去重,不适用于目录

搬目录这一场景,/J是最优解:不需要管理员权限,跨盘可用,对应用程序完全透明——程序按原路径打开文件,操作系统在文件系统层把路径重定向到新位置,应用根本感知不到差别。

命令格式是mklink /J "链接路径" "目标路径",注意两个参数的顺序,第一个是"假路径"(程序访问的路径),第二个是"真路径"(数据实际存放的位置),写反了会创建一个完全相反方向的链接,排查起来很费时间。

4.2 一次完整的搬迁记录,从复制到验证

假设要把某个占 26G 的目录%LOCALAPPDATA%\HeavyApp搬到D:\LocalMove\HeavyApp,完整流程如下,每一步都有存在的理由。

第一步,彻底关闭相关进程。不是关窗口,是去任务管理器确认没有残留进程,必要时在服务里停掉相关工作项。只要还有一个文件被占用,后面的复制就可能丢文件。

第二步,用 robocopy 复制,而不是拖拽。robocopy 的优势是能保留时间戳、权限、属主,且支持断点式的重试:

robocopy "C:\Users\me\AppData\Local\HeavyApp" "D:\LocalMove\HeavyApp" /E /COPY:DAT /DCOPY:DAT /R:1 /W:1 /MT:8 /LOG:C:\temp\move.log

参数逐个说:/E复制所有子目录含空目录;/COPY:DAT复制数据、属性、时间戳(用/COPYALL会连审核信息一起复制,普通账户没这个权限,会报一堆错,反而干扰判断);/DCOPY:DAT让目录的时间戳也保持一致,这一点很重要,因为有些应用靠目录修改时间判断缓存是否有效;/R:1 /W:1表示失败只重试一次、等一秒,避免卡在某个坏文件上死循环;/MT:8开 8 个线程加速;/LOG把过程写进日志,出问题能回溯。

第三步,核对。复制完不要急着删源,先比对两边的文件数和总大小。资源管理器看属性最直观,或者用(Get-ChildItem -Recurse -File | Measure-Object).Count分别统计。数字一致再往下走,差几个文件就要查日志里哪几个被跳过了。

第四步,改名而不是删除。把原目录重命名为HeavyApp_bak。这一步是关键保险——如果链接建错了,把名字改回来就能恢复原状,一分钟的事;如果直接删了,就只能重装应用。

第五步,建链接。在普通命令行窗口(不需要管理员)执行:

mklink /J "C:\Users\me\AppData\Local\HeavyApp" "D:\LocalMove\HeavyApp"

成功会提示"为 ... 创建的联接"。此时去资源管理器双击那个目录,如果能看到内容,说明链接生效。

第六步,启动应用验证。这一步别省。很多应用第一次启动会重新扫描自己的数据目录,如果链接有问题,这时候就会暴露:报错、闪退、或者数据"消失"。验证通过后,正常使用三到七天,确认没有异常行为,再删掉HeavyApp_bak释放空间。

4.3 搬迁的三个风险点,踩过才知道疼

风险一,应用更新会重建目录。这是最常见的问题。某些应用在自动更新时会删掉自己的目录再重新创建,这一删,链接就没了,更新后的新数据会老老实实写回 C 盘。表现是"搬完过了两个月 C 盘又满了"。所以在搬完之后的头几次应用更新后,要回头看一眼链接还在不在,dir一下父目录,看那个条目显示的是<JUNCTION>还是<DIR>。

风险二,目标盘符变化。如果把数据搬到了移动硬盘或者可随时插拔的盘上,盘不在的时候应用会直接报错,而不是优雅降级。所以搬迁目标必须是长期在线的内置盘。另外,如果目标盘是外接盘,某些加密或休眠场景下盘符可能变化,链接就断了。

风险三,目标盘被云同步工具监控。把数据搬到某个自动同步的目录下,几十万个缓存文件会被同步工具逐个扫描、逐个上传,CPU 和网络瞬间打满,同步盘自己也会因为文件太多而卡死。搬迁目标要选一个明确排除在同步范围之外的路径。

提示:建好的链接在系统还原、备份、磁盘克隆工具里的表现不太一致。大多数备份工具会把链接当链接处理(不重复备份数据),但也有些会顺着链接把数据再复制一份。搬迁之后如果要做整盘备份,先确认备份软件的行为,免得备份体积翻倍。

5. 安全删除的边界与常见问题排查

5.1 五类禁区:删了大概率要重装

清理这件事,知道"不能删什么"比知道"能删什么"更重要。下面这五类,我建议直接列进黑名单,任何教程让你删都别听。

第一类,Packages下的整个包目录。%LOCALAPPDATA%\Packages\<包名>\是商店应用的数据根目录,里面有LocalState(应用自己的数据,比如笔记、设置)和LocalCache(缓存)。删整个包目录等于把应用数据清空,有些应用会直接起不来。只清LocalCache和Temp子目录。

第二类,浏览器与客户端的User Data根目录。前面说过,书签、密码、扩展、登录态全在里面。清理路径必须精确到Cache级别的子目录。

第三类,授权与激活相关的缓存。目录名里带License、Activation、Token、Credential的,删了轻则要重新登录,重则要重新走一遍授权流程,某些离线授权场景下根本恢复不了。

第四类,密码库与证书目录。密码管理器的本地数据库、开发用的 SSH 私钥、证书存储,这些不是"缓存",删了没有第二次机会。%USERPROFILE%\.ssh、各类.pem、.pfx、.kdbx一律不碰。

第五类,正在被容器或虚拟机使用的虚拟磁盘。直接删.vhdx、.vmdk这类文件,等于把整个虚拟环境连数据一起销毁。要回收空间只能用压缩(compact)的方式,不能用删除。

5.2 删除方式的选择,以及"删了空间没回来"怎么办

同样是删除,方式不同效果差别很大。

**普通删除(Delete 键)**进回收站,回收站本身占空间。Windows 默认给回收站分配卷容量的 5%(最大可设到 10%),一个 500G 的盘就是 25G。如果经常删大文件,回收站会变成隐形的大户。可以右键回收站 → 属性,把上限调小到 1% 到 2%,或者干脆设为"不将文件移到回收站"——代价是误删无法恢复,自己权衡。

Shift + Delete直接绕过回收站,适合已经确认要删的大体积目录,省一次"删了再清空回收站"的操作。

命令行Remove-Item -Force -Recurse适合批量、带条件的删除,但有个坑:它遇到被占用的文件会中断并报错,而且不会告诉你具体哪个文件卡住了。加-ErrorAction SilentlyContinue能跳过,但你也就失去了排查线索。所以大批量删除时,我习惯先跑一遍"只统计不删除",看清有多少文件,再执行。

删完之后空间没释放,这是最常见的困惑。原因通常有三个。一是有进程还持有已删除文件的句柄,文件在目录里看不见但磁盘块没释放,重启后自动恢复。二是卷影副本(系统还原点)占着空间,那些"删掉"的旧文件还在还原点里,需要在系统保护里调小配额或删掉旧还原点。三是 SSD 的 TRIM 需要时间生效,尤其在长时间高负载之后,等一会儿或者手动执行优化驱动器即可。排查顺序就按这个来,先重启,再看还原点,最后看磁盘状态。

文件被占用查不出是谁的时候,用系统自带的资源监视器:性能监视器 → 资源监视器 → CPU 标签页 → "关联的句柄"搜索框里输入文件名,能直接列出占用进程和 PID。比装第三方工具省事,也更可控。

5.3 常见问题速查表

现象常见原因处理方式
删除时提示"文件正在使用中"进程未退出(托盘残留、后台服务)任务管理器结束进程,或用资源监视器按句柄反查
删掉大目录后可用空间没变回收站未清空 / 卷影副本占用 / 句柄未释放清空回收站 → 调小还原点配额 → 重启
清完缓存后应用打不开误删了配置或数据目录,不只是缓存立即用备份或被改名的.bak目录恢复,别再继续清
搬迁后目录显示为普通文件夹应用更新时重建了目录,链接被覆盖重新执行搬迁流程,把链接再建一次
目录体积统计比实际占用小很多统计时漏了隐藏文件或权限受限文件命令加-Force,或用管理员身份运行
清理脚本执行报一屏红色错误大量文件被占用,属正常现象改用-ErrorAction SilentlyContinue,或先关闭应用
磁盘清理工具清完还是红的大头在 Local 里,工具不覆盖用户目录按本文第 3 章的路径逐类处理

5.4 我自己反复踩到的几个坑

第一个坑是把"清缓存"和"清数据"当成一回事。早期我为了省事,直接对着一个不认识的大目录右键删除,结果某天打开软件发现所有本地草稿没了。后来才明白,很多应用把用户生成的内容和缓存放在同一个父目录下,只是子目录名不同。现在我的原则是:任何一个目录,在删除之前先点进去看一层,看看里面是哈希命名的乱码文件(缓存),还是有意义的文件名(数据)。这个动作只要五秒钟,能避开九成的误删。

第二个坑是在磁盘快满的时候做搬迁。C 盘只剩 2G 的时候去搬一个 26G 的目录,复制过程中系统临时文件一写,直接卡死。搬迁大目录之前,先确保目标盘有余量、C 盘至少有 5G 以上空闲,否则先清 Temp 腾点空间出来再搬。

第三个坑是过度依赖"一键清理"。有次图省事用了某工具的深度清理,结果它把我的开发缓存目录连带源码索引一起清了,IDE 重新索引花了四十分钟。从那之后我就只信自己写的白名单脚本——慢一点,但每一步都知道自己在干什么。

最后分享一个我觉得最实用的习惯:给 Local 下的所有大目录做一次"月度体检"。月初花十分钟,跑一遍统计脚本,把体积排前二十的目录看一眼,跟下个月的对比。绝大多数时候大部分目录是稳定的,突然涨起来的那个,往往就是最近装的某个软件在无节制地写缓存。抓这种"异常增长",比定期全盘清理有效得多,也更不容易误伤。

清理这件事说白了就三点:先量化再动手,分清缓存和数据,删除之前留退路。剩下的都是细节。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进