傳統遞迴 FindFirstFile/FindNextFile 計算目錄大小,在深層、大量檔案目錄下極其緩慢。Windows **Scripting Runtime (scrrun.dll)** 提供的 FileSystemObject 內建 Folder.Size 屬性,由 Shell 快取直接回傳,**速度快數個數量級**。本文示範 C++Builder 透過 COM 呼叫的極簡實作。
#include // Variant, COM 支援
void __fastcall GetFolderSizeFast()
{
Variant fs = Variant::CreateObject("Scripting.FileSystemObject");
Variant folder = fs.OleFunction("GetFolder", "D:\\Winnt"); // 目標路徑
Variant size = folder.OlePropertyGet("Size"); // 取得 Size 屬性 (bytes)
ShowMessage("目錄大小: " + size + " bytes");
// 約 1.2 GB → 顯示 1288490188
}
Variant::CreateObject:建立 COM 物件 (Scripting.FileSystemObject 需系統已註冊 scrrun.dll,Windows 內建)OleFunction("GetFolder", path):呼叫方法取得 Folder 物件OlePropertyGet("Size"):讀取屬性,回傳 64-bit 整數 (Variant 型別自動轉換)| 優點 | 缺點/限制 |
|---|---|
| 極快 (毫秒級) | 需 COM 初始化 (CoInitialize),VCL 應用程式通常已自動處理 |
| 程式碼極簡 | 依賴 Shell 快取準確性 (極少數情況下可能未更新) |
| 支援網路路徑 (UNC) | 無法取得單一檔案大小 (需 File.Size) |
| 自動處理 64-bit 大小 | 無法排除特定副檔名/隱藏檔 (為整個目錄樹總和) |
若需強制重新計算,可先呼叫 folder.OleProcedure("Refresh"),但會退化回遞迴掃描速度。
現代應用可使用 StorageFolder.GetBasicPropertiesAsync() (UWP/WinRT) 或 GetCompressedFileSizeTransacted 等原生 API,不依賴 COM/Scripting Runtime。