昨天下午在旧硬盘里翻到那个名为「2019_49index」的文件夹时,我其实没抱太大期望。硬盘是 2018 年买的,2TB 的机械盘,之前一直放在抽屉里,接口上还贴着当时怕混淆写下的标签纸,字迹已经有些褪色。打开之后里面只有 3 个文件:一个 1.2GB 的缩略图缓存包、一份 47MB 的 cache 目录,以及一个 12KB 的 SQLite 索引,扩展名被改成了 .db49。索引文件的修改时间停在 2019 年 11 月 3 日 23:47,那正好是我记得最后一次整理图库的晚上。但打开它的时候,sqlite3 直接抛了 DatabaseError,提示 malformed。用十六进制编辑器看,文件头部魔数还在,说明它原本确实是一个 SQLite 数据库,损坏的位置集中在第 12 页到第 31 页,恰好是路径表所在区域。
我先做了一件笨办法的事:把那份 1.2GB 的缩略图缓存包完整拷贝了一份到工作盘,然后用文件签名扫描工具重新识别里面的 JPEG 数据流。扫描结果一共找到 1136 个完整的图像片段,其中 971 个可以正常打开,剩下的 165 个在尾部有截断。这个数字和缓存包内部的文件数量对不上,说明缓存当初写入时就不是全量的。朋友林澜在 2021 年备份过一份缩略图包,大小 863MB,分区格式是 exFAT,她当时用的是移动硬盘。这份备份成了交叉验证的基准,我用它比对出了 214 张可以确认恢复的图片,编号从 00045 到 00258 中筛选得到。比对的方法很土:先按文件大小分组,再对相同大小的文件算 MD5,最后人工确认了十几组看起来相似但内容不同的缩略图。这一步花了将近三个小时,但值得,因为它给了我一个可验证的参照集。
再说那个损坏的索引。我用 Python 的 sqlite3 模块直接读,捕获异常后从底层页偏移去取记录,第一条可读的路径映射是一个以 /gallery/ 开头的相对路径,后面跟着一个文件大小和一个时间戳。时间戳转换成可读格式是 2019-11-03 21:16:44,和缓存包内某几个文件的创建时间吻合。这个发现让我确认了索引里至少有一部分记录是可信的。我接着写了一个小脚本,按照 SQLite 的页格式逐页解析,跳过损坏的页,对损坏页则用相邻页的单元格指针去推断可能的记录边界。最终从 12KB 的索引里恢复了 47 条完整记录,以及 31 条部分可读的记录。47 条这个数字后来成了我写回图片的依据。凌晨两点十二分,我把恢复出来的图片按原目录结构写回了 47 张,写回之前做了三份校验:文件大小、CRC32 和时间戳。47 张里有 41 张完全通过,剩下 6 张的 CRC 对不上,我标记为待人工复核。说实话,这个结果比我预期的要好,但我不认为这种运气可以复制。
有一个观点我想单独说清楚:很多人把「恢复」理解成把文件找回来就结束了,但真正麻烦的是找回之后的归属确认。恢复49图库误删图片这件事,如果只追求数量,用签名扫描可以轻松得到上千个图像片段,但其中相当一部分可能是缩略图、临时文件或完全无关的缓存碎片。我的判断是,没有索引或元数据佐证的「恢复」只能算半成品。这也是为什么我花了更多时间在交叉比对而不是扫描本身。那 6 张 CRC 对不上的图片,我最终没有放进恢复目录,而是单独放在一个待核验的文件夹里。这个决定在有些人看来过于保守,但我觉得值得。
顺带说一句,qq浏览器2020旧版的缓存目录结构在这次比对里帮了大忙。那台 2016 年的 ThinkPad 里,用户数据目录下有一个 47MB 的 cache 文件夹,修改时间与索引文件的最后写入时间完全吻合,误差不超过两分钟。缓存目录里的文件名是哈希值,没有扩展名,但文件头信息可以识别出 MIME 类型。我用这个目录里的 312 个缓存文件与缩略图包做了第二轮比对,又确认了 29 条记录。硬盘的 SMART 信息显示通电时间 18764 小时,重映射扇区 0,但坏道检测在 63% 位置扫出了两处读取延迟超过 800ms 的扇区,正好对应索引文件所在区域。这解释了索引损坏的物理原因,也提醒我那块盘不适合再作为主备份盘使用。
关于这类图库恢复的路径,我还整理过一份相关材料,涉及澳门49码12生肖资料页的本地快照与索引重建,以及图49恢复正常使用免费打开49图库免费下载所指的工程操作流程。快照本身并不完整,但配合外部的文本索引,可以还原出当时页面上的映射关系表,我核对了两份不同来源的存档,差异只有三处。这些材料放在一起看,会发现一个共通的问题:真正决定恢复成功率的不是工具的强大程度,而是你手里有没有足够的参照物。索引、缓存、快照、备份,任何一样单独存在都只能提供部分线索,组合起来才构成可验证的证据链。这个结论在我看来比任何单一技巧都重要,虽然它听起来并不像一句让人兴奋的话。
那天凌晨收工的时候,窗外已经有点亮了。我把恢复出来的 41 张图片按原目录结构整理好,把 6 张待核验的单独归档,然后在记事本上又写了一遍那条规则:永远不要覆盖原目录,恢复操作的第一步永远是拷贝一份只读镜像。这条规则后来帮我避开了至少两次潜在的二次破坏。硬盘放回抽屉之前,我把索引文件也一起拷贝了出来,留了一份到工作盘里。现在那份 12KB 的残破索引还在我桌面上,文件名后面我加了个「_recovered」的后缀。每次看到它,我都会想起那个 23:47 的时间戳,以及我用了六个小时才把那 47 条记录重新拼回去的夜晚。