那一夜,硬盘里的目录树与 2019 年的编号
一月十九号夜里十一点四十,我把那块落灰的 2TB 移动硬盘插回电脑。风扇转起来的声音比记忆里响,指示灯闪了十七下才稳定下来——这个数字我记得清楚,因为当时我正拿手机拍屏幕,准备发给三年前一起做目录的老同事周衍。要找一个 2019 年存下的老索引表,文件夹名叫 tuku-old-2019,点开以后第一层有 41 个目录,按说这是当年最规整的一次归档,可第二层往下就乱了:有的目录里套着 zip,有的直接把图片按日期平铺,还有三个目录的名字是「新建文件夹(2)」「新建文件夹(5)」「新建文件夹(7)」,括号里的数字跳着走,说明中间有两次误删。我盯着那份残缺的层级看了大概二十分钟,脑子里冒出来的第一个念头不是「怎么修」,而是「原来这就是恢复原来的49图库492在个人硬盘上真实的样子」——它从来不是一键还原,而是一次收尸。
我先把根目录导出成一份纯文本清单,命令是 dir /s /b > list-0119.txt,跑完一看,一共 12,847 行。这个数字比我预想的多,因为里面混进了大量缩略图缓存和重复下载的副本。周衍在微信那头回了一句:「先别删,全留,等索引表回来再对。」他这人说话一向短,但这句话后来救了我——里面有一批文件名被浏览器改过前缀,靠肉眼根本认不出原始编号。于是我把清单按扩展名分组,图片 9,412 个,压缩包 1,306 个,剩下的是网页存档和零散的 txt,其中网页存档又分成 mht 与 html 两批,前者多半是 2019 年之前抓的,后者是后来补的。这一步做完,已经是凌晨一点出头,我泡了第三杯茶,才开始想「收录」这件事本身的边界。
收录的第一原则:先留全,再谈对错
做收录的人容易犯一个错,就是一开始就想「哪些该留」。我在 2021 年整理别的东西时也这样,结果删掉一批当时看着像垃圾的文件,半年后才发现那是唯一一份带时间戳的版本。所以这次我给自己定了个很笨的规矩:凡是不确定归属的,先进 pending 目录,编号前缀统一加 p_,等索引表恢复之后再决定去留。pending 里最后留了 2,183 个文件,占全部条目将近六分之一,这个比例听起来夸张,但你把浏览器缓存、重复副本、改名副本三类加在一起,其实合理。清点的时候我特意没有用批量重命名工具,因为那类工具在遇到同名文件时会自动加后缀,加着加着就把原有的编号规律打散了——这一点我在 2020 年吃过亏,之后再也不敢偷懒。
「对错」这件事则要等到索引表回来才能谈。那份老索引表不是数据库,是一个用制表符分隔的 txt,字段只有五个:编号、分类、来源、抓取时间、备注。它最早的样子我见过,是周衍用脚本生成的,时间戳精确到秒,所以后来任何一次「恢复」都可以拿它当校验基准。问题在于,我手上这份是 2019 年 8 月的快照,之后还追加过两轮,那两轮的增量没有合并进来。三月的时候我在一篇讲 澳门正版资料图库查询 的笔记里提过类似的困境:索引的完整性往往不取决于你有多努力,而取决于你上一次备份时有没有偷懒。这句话放到今天依然成立,甚至更刺人。
校验:拿五个字段反推丢失的那一段
索引表回来以后,真正花时间的是比对。我写了个很土的脚本,把清单里的文件名去掉扩展名,再截掉浏览器加的前缀,跟索引表的「编号」字段做交集,先算出能对上的有 8,904 条,对不上的 3,943 条。对不上的这批里,有 1,200 多条其实是同一张图的不同尺寸——原图、缩略图、移动端裁切版,文件名只差一个后缀字母,靠模糊匹配能把它们聚成 612 组。剩下的两千出头才是真问题:要么编号在索引表里没有,要么索引表里有而文件不在。前者多半是 2019 年之后补抓的,后者则是当年误删。我把这两类分别记成 orphan-file 与 orphan-row,每一条都写进一张对照表,表头是编号、文件名、判定、依据、处理。这张表后来长到 2,047 行,打印出来有三十多页,我把它夹在一个透明文件夹里,放在书桌右手边,翻得纸角都卷了。
比对过程中有个细节值得单说。索引表的「备注」字段里,有 176 条写着「待补」,另有 58 条写着「重复,见上一行」。这 234 条是最难判的,因为它们本身就带着不确定性。我的处理是:凡是备注含「待补」的,一律进 pending,不进主目录;凡是「重复,见上一行」的,逐条人工确认上一行的编号是否存在,存在就合并、不存在就升格为独立条目。这个规则听起来机械,但执行起来极耗神,尤其到第一百多条的时候,人会开始怀疑自己是不是在给一堆没人看的文件做无用功。我当时也怀疑过,直到翻到一条 2019 年 6 月 3 日的记录,备注写着「客户要的原图,别删」,后面跟着一串编号。那一刻我意识到,这些字段不是给机器看的,是给三年前那个熬夜的人看的,而他当时并不知道自己会不会再回来。
一个不太受欢迎的判断
说到这里,我要放一句可能不太好听的话:绝大多数关于「恢复原来的49图库492」的教程,把顺序搞反了。它们通常先教你怎么用工具批量恢复、怎么一键去重、怎么按哈希比对,这些手段本身没错,但它们是第二步。第一步永远是承认这份东西已经碎了,并且搞清楚碎在哪一层——是文件系统层面的丢失,还是索引层面的缺失,还是编号规则本身在某一轮改名里被覆盖。我见过太多人上来就跑恢复软件,跑完得到一个更大的、更难对的文件堆,然后彻底放弃。这不是技术问题,是顺序问题。你手上如果没有一份像样的清单,任何恢复工具给你的都只是「更多的东西」,而不是「原来的东西」。这个判断我在一次线下分享里讲过,当场有人不同意,说工具已经很智能了。我承认工具在进步,但智能的前提是输入干净,这一点五年内不会变。
整理的后半程:从对照表到可检索的索引
对照表做完之后,剩下的工作反而顺手。我把主目录按「编号段」重新分了区,每 500 个编号一个文件夹,文件夹名直接用起止编号,比如 0001-0500、0501-1000,这样一眼就能定位。分区的时候发现编号并不连续,中间有 11 段空号,最长的一段从 1847 跳到 1902,缺了 55 个。这些空号我没有强行补齐,而是在索引里保留成「占位行」,标注 missing 和最后一次出现的时间。保留空号这件事有争议,有人觉得索引应该干净,空行是噪音;我的看法相反,空号本身就是信息,它告诉你这份东西在哪里断过,而断点往往比内容更能说明它经历过什么。这一点在我写 49库图库恢复方法 那篇长文时也反复提到,只是那时候例子没这么具体。
可检索化是最后一步,也是最容易被省略的一步。我给每个条目补了三个字段:文件的实际路径、最后一次修改时间、以及一句不超过二十字的描述。描述这件事没法自动化,只能一条条写,写到第五百条的时候手都麻了。但写完以后效果立竿见影:以前找一张图要翻目录,现在搜一个词就能出来。这让我想起去年冬天帮朋友处理浏览器的问题,他在 qq浏览器打开app不跳转 的排查里折腾了一整晚,最后发现只是缓存目录指错了地方,跟索引错位是一个道理——问题不在内容,在指向内容的那一层。技术上的事,十有八九坏在中间层。
顺便说一句,整理过程中我还顺手核对了一批历史条目。浏览器那边的入口这几年改过几轮,早年的路径记录和现在的对不上,我在 新版qq浏览器私密入口在哪 的记录里留了一份对照,主要是给以后自己查方便。至于更早的浏览痕迹,我一般用 历史看过的网站 里提到的方法做时间线回溯,配合索引表的时间戳,能把「什么时候抓的、什么时候改的」串起来。这些交叉验证做多了,你会对一份文件的「生平」产生某种奇怪的熟悉感。
收尾:疲惫但值得
一月二十二号凌晨两点十七分,我把最终的索引文件导出,大小 3.4MB,行数 9,018,其中有效条目 8,904、占位 114。这个数字和一开始的 12,847 对不上,因为去掉了重复副本、缓存和无法归属的缩略图,差值都能在 pending 对照表里找到解释。导完之后我没有马上关电脑,而是把那份 txt 从头翻到尾,翻了大概四十分钟。翻到中间某一页,看到一条 2019 年 5 月 11 日的记录,备注只有四个字:「先这样吧」。我盯着那行看了很久,因为三年前写下它的人大概也没想到,这份「先这样吧」的东西,会在三年后被另一个人一条一条捡回来。收尾的时候我给自己倒了最后一杯茶,茶早凉了,但那一刻确实觉得,疲惫是值得的。
写下来,是为了让下一次恢复不用再从零开始。所以这篇东西没有结论式的总结,只有一张还在更新的表和一句话:先把东西留全,再谈它是不是原来那个。至于「恢复原来的49图库492」到底算不算完成,我不敢下断言,因为索引这种东西,永远是下一轮校验才算数。我能确定的是,今晚这块硬盘可以拔了,目录树是干净的,对照表是完整的,而那个写着「先这样吧」的人,如果哪天回来找,会看到一条没断的线。