C 盘清理瘦身 + 数据迁移(通用技能)
适用场景
「C 盘快满了」「磁盘空间不足」「清理缓存」「给 C 盘瘦身」「把 XX 挪到 D 盘」。目标可能是系统缓存、开发工具链、第三方软件数据,也可能是用户个人目录——先判断目标属于哪一类,再选择手段。
核心原则(不可违背)
- 先扫描,后动手。第一轮只出报告(路径、体积、最后修改时间),不删任何东西,等用户确认清理档位。
- 分档清理:A=免确认可直接删(纯缓存、可自动重建);B=需用户确认;C=引导用户在管理员终端手动执行;D=禁止触碰。
- 个人文件安全红线:Desktop / Downloads / Documents / Home 目录下的任何文件,扫描只读、删除必走回收站、单批 ≤10 个、每批核验、失败即停。绝不
rm -rf/del /S /Q个人目录。 - 迁移前必备份:任何移动/重命名/删除前,先
robocopy /E复制出完整备份并确认成功,再告知用户备份位置。 - 收尾必须报告:
df -h /c前后对比 + 未能清理项及原因。
第一部分:摸底扫描(每次必做的第一步)
# 总体水位
Get-PSDrive C, D
# C 盘根目录一级占用(排除符号链接/junction,否则会重复统计)
Get-ChildItem C:\ -Directory -Force -ErrorAction SilentlyContinue |
Where-Object { $_.LinkType -eq $null } |
ForEach-Object {
$s = (Get-ChildItem $_.FullName -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.LinkType -eq $null } |
Measure-Object Length -Sum).Sum
[PSCustomObject]@{ GB = [math]::Round($s/1GB, 2); Path = $_.FullName }
} | Sort-Object GB -Descending | Select-Object -First 20
避坑:
C:\Users\<user>\AppData\Local\Application Data等是指向自身的软链接,遍历时会无限递归报出夸张数值(如 25G),必须用LinkType -eq $null排除 reparse point。C:\System Volume Information(系统还原点)没有管理员权限读不到,但可能是几十 GB 的隐形大户——在报告里单独注明「需管理员权限评估」。pagefile.sys/hiberfil.sys在文件系统层面看不到常规体积,用Get-ChildItem C:\ -Force -File才能显示,别漏估。
逐层下钻定位大头后,按下面第二~四部分对号入座。
第二部分:分档清理清单
A 档 —— 免确认直接清(纯缓存,可自动重建)
| 类别 | 位置 | 说明 |
|---|---|---|
| 用户临时文件 | %TEMP%(AppData\Local\Temp) | 跳过被占用的(WinError 32 正常) |
| 系统临时文件 | C:\Windows\Temp | 同上 |
| Windows 更新缓存 | C:\Windows\SoftwareDistribution\Download | 建议先 net stop wuauserv,删完再启动 |
| 传递优化缓存 | 设置→系统→存储→传递优化,或 Delete-DeliveryOptimizationCache | |
| 崩溃转储 | AppData\Local\CrashDumps、C:\Windows\Minidump | |
| 着色器缓存 | AppData\Local\NVIDIA\{DXCache,GLCache}、AMD 等价目录 | 自动重建 |
| 缩略图/图标缓存 | AppData\Local\Microsoft\Windows\Explorer\thumbcache_*.db | 需先关 explorer.exe,收益小放最后 |
| 第三方更新包残留 | AppData\Local\*-updater\(各类软件的 updater 目录,单个可达 500 MB) | 删了不影响软件本体,下次更新重新下载 |
| npm 缓存 | AppData\Local\npm-cache(2 万+小文件很常见) | 优先 npm cache clean --force 走官方通道 |
| pip 缓存 | AppData\Local\pip\cache | pip cache purge |
| 回收站 | Clear-RecycleBin -DriveLetter C | 先问一句:里面可能有用户想找回的东西,视为 B 档 |
B 档 —— 需用户逐项确认
| 类别 | 位置 | 风险与说明 |
|---|---|---|
| 浏览器缓存 | Chrome/Edge 的 AppData\Local\...\User Data\Default\Cache 等 | 关浏览器后清;登录态/书签/扩展不要动 |
| 闲置虚拟环境 | conda envs、venv、.virtualenvs | 需用户确认哪个还在用;删除用 conda env remove/直接删目录 |
| 闲置开发运行时 | 旧版 Node/Python/JDK 等版本目录 | 保留最新 1-2 个;当前在用版本不要删 |
| Docker 镜像/卷 | Docker Desktop 的 WSL 数据盘 vhdx | 引导 docker system prune -a,让用户确认 |
| 聊天软件接收文件 | 微信/QQ 的聊天文件目录(常在 Documents 下,可达几十 GB) | 个人数据,只做扫描报告+建议用软件内「存储清理」,绝不代理删除 |
| 下载目录大文件 | Downloads | 只列报告(路径/大小/日期),标注哪些像安装包可重下,由用户逐个决定 |
| Windows.old | C:\Windows.old(升级残留,可达 20-40 GB) | 引导「存储感知→删除以前的 Windows 安装」,10 天后系统自动删 |
| 系统还原点 | C:\System Volume Information | 见 C 档 |
C 档 —— 引导用户在管理员终端手动执行(Agent 提权通常会被拦截,不要尝试绕过)
- 休眠文件
C:\hiberfil.sys(4-8 GB):管理员终端执行powercfg /h off,代价是失去休眠与「快速启动」。 - WinSxS 组件存储(常占 8-15 GB,可压回 2-4 GB):
Dism /Online /Cleanup-Image /StartComponentCleanup(加/ResetBase更狠但之后无法卸载已装更新,需单独告知)。 - 磁盘清理完整版:
cleanmgr /d C:勾选所有项,或「设置→系统→存储→存储感知」。 - 系统还原点:
vssadmin list shadowstorage查看占用;「系统属性→系统保护→配置→删除」可释放,会丢失还原点,必须用户确认。 - 虚拟内存 pagefile:不要删,只能挪(见第三部分方案 5)。
D 档 —— 禁止触碰
C:\Windows(除 SoftwareDistribution\Download)、C:\Program Files、C:\Program Files (x86)内的软件本体C:\pagefile.sys(只能挪不能删)、C:\hiberfil.sys(只能引导用户关)- 任何用户明确说「别动」的目录
C:\Users\<user>\下非缓存的个人数据(只报告不代理)
第三部分:数据迁移到其他盘(瘦身治本手段)
清理只能救急,把持续增长的数据搬走才是治本。按目标类型选方案。
方案 1:目录联接(junction)—— 通用首选,适合绝大多数 AppData 大户
适用于:npm 全局目录、pip 缓存、聊天软件数据目录,以及任何「软件写死绝对路径」的目录。原理:把 C:\...\X 整体搬到 D:\CData\X,在原位置建 junction,所有绝对路径照常工作,程序无感知。
标准流程(必须在目标程序完全退出后执行):
- 检查进程:
tasklist | findstr <进程名>,确认退出。 - 备份:
robocopy "C:\...\X" "D:\CData\X.bak" /E /XJ /COPYALL /R:1 /W:1 - 搬运:
robocopy "C:\...\X" "D:\CData\X" /E /XJ /MOVE /R:1 /W:1 - 原目录改名留后路:
ren "C:\...\X" "X.bak-C"(若 /MOVE 已清空则直接建联接) - 建联接(cmd 内置命令,PowerShell 里要加
cmd /c):cmd /c mklink /J "C:\...\X" "D:\CData\X" - 验证程序正常后,删除
.bak-C与.bak备份(或保留一周再删)。 - 任一步失败立即回滚:删联接 →
ren X.bak-C X或把 .bak 拷回来,绝不留半成品状态。
验证:fsutil reparsepoint query "C:\...\X" 确认联接;dir 看联接标记 <JUNCTION>;对比源/目标文件数一致。
注意:符号链接(/D 软链接)跨目录引用部分程序不认,junction(/J)兼容性最好;两者都不需要管理员权限(目录联接)。
方案 2:WSL 发行版迁移(vhdx 大户,动辄 10-50 GB)
# 新版 WSL 优先用内置搬迁:
wsl --manage <发行版名> --move D:\WSL\<发行版名>
# 旧版用 导出→注销→导入:
wsl --export <发行版名> D:\wsl-backup.tar
wsl --unregister <发行版名>
wsl --import <发行版名> D:\WSL\<发行版名> D:\wsl-backup.tar
# 注意:--import 后默认用户变 root,需在 /etc/wsl.conf 里加 [user] default=<原用户> 后 wsl --shutdown 重启
导入后 vhdx 不会自动收缩:Optimize-VHD -Path <vhdx> -Mode Full(需 Hyper-V 模块)或 wsl --shutdown 后 diskpart → select vdisk file=... → compact vdisk。
方案 3:Docker Desktop 数据迁移
Docker 的 WSL 数据盘 docker_data.vhdx 巨大。做法:Docker Desktop → Settings → Resources → Advanced → Disk image location 改到 D 盘(官方通道,最省事);或先 docker system prune -a 瘦身再迁移。
方案 4:系统自带「位置」选项卡 —— 适合用户个人目录
Documents/Downloads/Desktop/Pictures 等个人目录不要用 junction(部分系统组件会有兼容问题),正确做法:资源管理器 → 右键目录 → 属性 → 「位置」选项卡 → 移动到 D 盘。系统会自动迁移文件并更新所有已知路径引用。引导用户操作即可,Agent 不代做。
方案 5:虚拟内存挪盘
控制面板 → 系统 → 高级系统设置 → 性能设置 → 高级 → 虚拟内存:取消 C 盘自动管理,在 D 盘设置系统管理的大小。需要重启。
第四部分:执行中的已知陷阱
删除方式选择
- 个人文件:先备份(
robocopy /E到明确路径)→ 走回收站(PowerShell 调[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($p,'OnlyErrorDialogs','SendToRecycleBin'))→ 单批 ≤10 个 → 每批核验 → 失败即停。 - 批量缓存目录:用 Python/PowerShell 脚本一次执行,不要逐条循环删(每条都走完整删除管线会超时)。
回收站的性能陷阱(重要)
Windows 把删除改道为「移入回收站」时,对上万小文件的目录(如 npm _cacache 2 万个文件)会慢到超时——实测走回收站 22 分钟跑不完,原生永久删除 30 秒清完。永久删除只可用于用户已明确确认、且内容可重建的纯缓存;对个人文件或不可重建数据绝不可用,必须走回收站。
删除报 WinError 5(拒绝访问)的排查顺序
- 查 ACL:
icacls <文件>。若带(DENY)(拒绝删除)条目:icacls "<目录>" /remove:d <用户名> /T /C移除 DENY 条目后重试,通常立即成功。 - 清只读属性:
os.chmod(p, stat.S_IWRITE)——DENY ACL 时无效。 chmod+remove全失败但icacls显示(F)完全控制 → 基本是 DENY ACE,走第 1 步。- WinError 32(文件被占用)→ 正常,跳过,收尾时列入「未能清理项」;提示用户关闭相关程序或重启后再清。
第五部分:收尾报告模板
- C 盘(及目标盘)可用空间前后对比,给出释放总量。
- 分档列出:已清理项及各自体积 / 需用户手动执行的 C 档项(附具体命令)/ 被占用跳过的项 / 建议迁移的持续增长大户。
- 若识别到持续增长源(日志、缓存、vhdx、聊天文件),主动建议对应的定期清理或迁移方案(第三部分)。
Scan to join WeChat group