⌨ 技术

C盘满了为什么还能发截图:一次0字节“损坏”背后的剪贴板原理

前言

前几天 C 盘彻底满了:资源管理器里显示 0 字节可用,共 249 GB,任何文件都写不进去。这时我按 Win+Shift+S 截了一张图,Ctrl+V 粘贴进微信——正常发送,对方也收到了。但过了一会儿想回头看那张图,发现截图工具自动保存到「图片\屏幕截图」文件夹里的 .png 打不开了,Windows 照片提示:

很抱歉,照片无法打开此文件,因为当前不支持该格式,或文件已损坏。

同一张截图:走剪贴板发的微信完好无损,走磁盘自动保存的文件却“损坏”了。这两条路径到底差在哪?剪贴板“复制到微信”的整个过程里,数据都待在什么地方?这篇文章把排查过程和背后的一整套原理(剪贴板、内存、上传链路)记录下来。

现象:两个矛盾的事实

先摆现象,当时我脑子里是一堆问号:

  • 截图明明保存在 C 盘,「屏幕截图 2026-09-12 210914.png」这个文件也确实躺在文件夹里——但打不开,提示“文件已损坏”;
  • 同一张图,粘贴到微信聊天框正常显示、正常发送,对方看起来毫无问题;
  • 前后几分钟的其它截图(磁盘稍微腾出一点空间之后保存的)又都完好,能正常打开。

所以第一个疑团不是“图坏了”,而是:C 盘都 0 字节可用了,为什么截图还能发出去?

验证:0 字节与 PNG 魔数

先别急着下结论,用命令看看文件的真实状态:

# 看文件大小
ls -la /c/Users/min/Pictures/Screenshots/*2026-09-12*.png

# 看文件头(PNG 文件的标准开头是 89 50 4E 47,即 .PNG)
od -A d -t x1z "屏幕截图 2026-09-12 210914.png" | head -3

结果一目了然:

文件 大小 文件头
屏幕截图 2026-09-12 210914.png(打不开的) 0 字节 空,什么都没有
同一张图在微信的显示缓存(RWTemp 目录,次日打开微信时才生成 5.6 KB 89 50 4E 47 … IHDR,标准 PNG
前后几天其它截图 130 KB ~ 5 MB 标准 PNG

真相:那张“损坏”的图根本不是损坏,是空的——C 盘满到极限时,截图工具的自动保存失败了,只在磁盘上留下了一个 0 字节的空文件(目录项建出来了,数据一个字节都没写进去)。照片应用读不到任何有效内容,只能报“格式不支持或已损坏”。而微信那边的副本是完整的,所以发送链路一切正常。

顺便解开一个小谜团:打不开的只有 21:09 那一张——从 21:30 起的几张就都正常了,因为那会儿我已经动手清理磁盘、腾出了空间。0 字节可用不是一个稳定状态,是”挤压极限”:清理前后,同样一张截图就是两种命运。

原理:截图从剪贴板到微信服务器的完整链路

搞清楚现象之后,我把整条链路拆成五步,每一步都值得单独说清楚。

1. 剪贴板不是文件,是系统托管的“带标签内存仓库”

Win+Shift+S 截图时,图像数据被放进剪贴板。很多人直觉上把剪贴板理解成“一个临时文件”,其实不是——剪贴板是 Windows 系统在内存(RAM)里托管的一块数据仓库,由操作系统统一管理,全程不落盘(除非你开了 Win+V 剪贴板历史,系统才会在磁盘另存一份历史记录)。

这就是整件事的核心答案:截图 → 粘贴 → 发送这条路,从头到尾不碰磁盘,所以 C 盘满了完全不影响它。

2. 内存里存的是什么:位图 + PNG 字节流

截图工具往剪贴板里放的不是“一个文件”,而是同一种数据的多种格式表示

  • 一份原始位图(DIB 格式,未压缩的像素点阵,屏幕上每个点的颜色值);
  • 一份 PNG 编码的字节流——这份的字节内容和 .png 文件完全一样(开头就是 89 50 4E 47 的 PNG 魔数)。

区别在于:它只是内存里的一段数据,没有文件名、没有路径,不是“文件”,只是恰好用了 PNG 的编码格式。

3. 微信怎么知道这是图片:格式 ID

剪贴板不是一坨匿名字节,每种数据都带着格式标签(格式 ID,比如 CF_DIB 表示位图,还有注册名为 "PNG" 的自定义格式)。

你按 Ctrl+V 时,微信调用系统 API 去问剪贴板:“你有没有位图/PNG 格式的数据?”——有,微信就把数据取过来,在输入框里渲染出图片预览。所以微信不需要“猜”也不需要看扩展名,系统 API 直接告诉它这是什么类型的数据。这也解释了为什么复制文字时微信显示文字、复制图片时显示图片预览:同一个剪贴板,格式标签不同而已。

4. 粘贴到发送框时存在哪:还在内存

Ctrl+V 的那一刻,只是把字节从剪贴板拷贝进微信进程的内存,输入框里看到的预览图就是从内存直接渲染的。此时磁盘上依然没有这个图的任何文件。

5. 点发送之后:socket 上传 + 一份加密存档(显示缓存是另一回事)

真正的”文件”直到你点发送才出现。微信做两件事,另外还有一件”下次打开才发生”的事:

  1. 上传:把内存里的图片字节(通常还会重新压缩)直接写进 HTTPS 网络连接,传到腾讯服务器。所谓”文件上传”,本质就是把这个字节流写进网络 socket,不需要先在本地落成一个”图片文件”;
  2. 写存档:同时在自己的数据目录里落一份加密存档——这才是”微信会把发送的图片保存一份在电脑里”的真正答案。我在 msg/attach 下找到了它,三份文件的创建时间是发送后一秒(21:10:06):

C:\Users\min\xwechat_files\wxid_xxx\msg\attach\<会话哈希>\2026-09\Img\f712bb95….dat (5.6 KB,标准版) C:\Users\min\xwechat_files\wxid_xxx\msg\attach\<会话哈希>\2026-09\Img\f712bb95…_h.dat (原图版,本次与标准版同大小) C:\Users\min\xwechat_files\wxid_xxx\msg\attach\<会话哈希>\2026-09\Img\f712bb95…_t.dat (2.6 KB,缩略图)

注意它是 .dat 而不是 .png:微信 4.x 用自己的加密容器格式(文件头带 V2 版本标记)把图片字节包起来,资源管理器里打不开、按图片也搜不到,只有微信自己能解。聊天记录里的图片能一直回看,靠的就是这份存档 + 服务器。

这里冒出一个更尖锐的问题:磁盘不是满了吗,微信怎么还能写进去? 因为"满盘"不是开关,是瞬时值,这两次写入隔了 51 秒、需求差了两个数量级:

  • 截图失败于 21:09:15,需要约 2.5 MB(六百多个 4 KB 簇);微信存档成功于 21:10:06,三个文件加起来只要 5 个簇(约 20 KB)
  • 0 字节可用时,文件目录记录(MFT 记录)走的是 NTFS 保留区、不占用户空间,需要空间的只有数据本身——所以截图留下的是"有文件名但 0 字节"的空壳,而不是文件不存在;
  • 系统和后台程序随时在删临时文件、滚动日志、清理缓存,满盘状态下几 KB 的空隙一直在产生又消失。微信的小文件晚到 51 秒、需求又小 100 倍,正好塞进了某次释放的缝隙里。

那一分钟具体是哪个进程释放了那 20 KB,事后无法精确还原(得翻 NTFS 的 USN 日志,需要管理员权限且大概率已被覆盖),但两次写入的结果互为物证:21:10:06 那一刻,磁盘至少还有约 20 KB。满盘从来不是"绝对 0 的静止状态",而是贴着零抖动的临界状态,谁赶上空隙谁活下来。 3. 写显示缓存(这一步发生在下一次打开微信时):我一开始以为 temp\RWTemp 下那个 .png 是发送时写的缓存,查了创建时间才发现完全不是——它是第二天早上 10:08、我打开微信的那一刻才生成的

8dc3d5ca….png 创建于 09-13 10:08(聊天窗口要渲染这张图) 8dc3d5ca….png_temp.bmp 创建于 09-13 10:08(同一秒)

过程是:聊天窗口需要显示这张图 → 微信把 msg/attach 里的加密存档解密(必要时才从服务器重新下载),写出一份显示用的 .png,紧接着解码成一张 363×145 的 BMP 位图_temp.bmp,文件头就是 BM)供界面直接渲染。所以 RWTemp 里放的是用完可删的显示缓存,不是发送存档——删了也没关系,下次打开聊天会重新生成一份。

回到最初的疑问

把链路画成一张表,矛盾的答案就全清楚了:

路径 数据待的地方 碰不碰磁盘 C 盘满的结局
截图 → 粘贴微信 → 发送 剪贴板/进程内存 → 网络 socket 发送后写加密存档时碰一次 存档(约 8 KB)写进去了,一切正常
截图 → 自动保存到「屏幕截图」文件夹 截图工具进程 → 磁盘写入 全程都碰 写入失败,留下 0 字节空文件

所以结论是:

  • 不是“截完图图坏了”,而是自动保存这条路径根本没把数据写进磁盘
  • 0 字节的文件救不回来(数据从来没写进去过),但内容没丢——微信的加密存档和聊天记录是完好的(第二天打开微信能正常显示、另存就是证明);
  • 磁盘满造成的文件失败有一个典型特征:文件存在但大小为 0,或者体积明显偏小。以后遇到“文件打不开提示损坏”,先看文件大小,说不定一眼就能定位。

尾声:磁盘满的教训

这次事后清了理,C 盘回到 7 GB 可用(98% 已用),截图保存恢复正常。但 0 字节可用对系统盘来说相当危险:Windows 更新会失败、虚拟内存交换文件写不进去会导致卡死,严重时甚至无法开机。经验值是给系统盘留出至少 10%~15% 的空闲

清理大头方面,我的情况里微信的 xwechat_files 数据目录是头号嫌疑人(聊天图片视频缓存会无限堆积),可以在微信设置里把存储路径改到其它盘;另外磁盘清理(cleanmgr)、下载文件夹和回收站也是常规回收点。

最后回顾一下这次真正学到的:“复制粘贴”从来不是魔法,它是内存中一段带着格式标签的数据,在系统剪贴板这个中转站里流转。 理解了这一点,很多日常困惑——比如为什么复制的东西换个软件就粘贴不出来、为什么剪贴板里的图片占内存却搜不到文件——就都有了答案。

评论区

共 0 条
🍃 还没有评论,沙发虚位以待~
🚇

穿越虫洞?

虫洞会把你随机传送到另一位陌生博主的网站——
可能是技术大佬,也可能是诗歌爱好者,开盲盒的时间到了。

森林精灵