首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 讀取 XP Thumbs.db 縮略圖快取檔案完整解析

     編輯:關於.NET

在 Windows XP 時代,圖片或影音資料夾中常見一個隱藏檔案 Thumbs.db,這是系統用來快取縮略圖的資料庫。有了它,資源管理員開啟大量圖片資料夾時不需即時產生縮略圖,顯示速度大幅提升。若能在自訂圖片管理程式中復用這些快取資料,便能無縫整合系統資源管理器的縮略圖功能。然而,Thumbs.db 的檔案結構與存取 API 並未公開,經研究發現其採用結構化儲存格式,這在 COM 時代廣泛使用,但在 .NET 中微軟未提供原生支援。

結構化儲存檔案概念

結構化儲存本質上是一個儲存在單一檔案中的檔案系統,包含「資料夾」與「檔案」的階層結構。類似 WinRAR 封裝多檔案的邏輯,它允許在不移動大量資料的情況下修改內容。以 Word 文件為例,若採用循序儲存,插入第一頁內容需移動後續所有頁面;若視為小型檔案系統,每頁為資料夾、段落為檔案,修改即變得靈活高效。

結構化儲存概念示意圖

COM 介面:IStorage 與 IStream

在 COM 中,IStorage 對應「資料夾」,IStream 對應「檔案」。IStorage 提供建立/開啟串流、建立/開啟儲存體、列舉元素、複製、移動、提交等方法;IStream 則提供讀寫、定位、鎖定、複製等操作,用法類似 .NET 的 System.IO.Stream。一般結構化儲存的資料夾中會有一個 IStream 保存目錄資訊。

Thumbs.db 內部結構分析

Thumbs.db 中包含一個名為 Catalog 的 IStream,儲存所有快取縮略圖的檔名列表,分為兩段:

  1. CatalogHeader:包含縮略圖尺寸、總數等資訊。
  2. CatalogItem 陣列:每筆包含檔名、修改時間、ItemId 等欄位。

由於缺乏官方文件,需自行定義對應結構,並注意記憶體配置順序:

[StructLayout(LayoutKind.Sequential)]
public struct CatalogHeader
{
    public short Reserved1;
    public short Reserved2;
    public int ThumbCount;
    public int ThumbWidth;
    public int ThumbHeight;
}

[StructLayout(LayoutKind.Sequential)]
public struct CatalogItem
{
    public int Reserved1;
    private int m_ItemId;
    public int ItemId { get { return m_ItemId; } set { m_ItemId = value; BuildItemIdString(m_ItemId); } }
    public DateTime Modified;
    public string FileName;
    public short Reserved2;
    public string ItemIdString { get; private set; }
    private void BuildItemIdString(int itemId)
    {
        var temp = itemId.ToString();
        var buffer = new char[temp.Length];
        for (int i = 0; i < temp.Length; ++i) buffer[i] = temp[temp.Length - i - 1];
        ItemIdString = new string(buffer);
    }
}

特別注意:Thumbs.db 內部資料採用倒序儲存(字串反轉、整數位元組反序),這增加了解析難度。

讀取 Thumbs.db 實作步驟

  1. 使用 StgOpenStorage 開啟檔案取得 IStorage 介面。
  2. 開啟 Catalog 串流讀取目錄結構。
  3. 解析 CatalogHeader 與 CatalogItem 陣列。
  4. 根據反序的 ItemIdString 開啟對應的縮略圖 IStream。
  5. 呼叫 IStream::Read 讀取影像資料(略過前 12 位元組表頭)。
  6. 將位元組陣列轉為影像顯示於介面。

.NET 僅內建 IStream 定義,IStorage 需自行定義或參考 pinvoke.net 現成定義。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved