取得資料夾總大小 (含子目錄) 是常見需求。本文提供一個健壯的 GetFolderSize 函數,使用 Win32 API FindFirstFile/FindNextFile 遞歸遍歷,返回 64 位元組大小 (DWORD64/ULONGLONG),並可選統計檔案數與子目錄數。
// 返回:資料夾總位元組大小
// dwFiles: 輸出參數,統計檔案總數 (可為 NULL)
// dwFolders: 輸出參數,統計子資料夾總數 (可為 NULL)
ULONGLONG GetFolderSize(LPCTSTR szPath, DWORD* dwFiles, DWORD* dwFolders)
{
TCHAR szFilePath[MAX_PATH];
TCHAR szFilter[MAX_PATH];
WIN32_FIND_DATA findData;
HANDLE hFind = NULL;
ULONGLONG totalSize = 0;
// 構建搜尋路徑: "C:\Folder\*.*"
_tcscpy_s(szFilePath, szPath);
PathAddBackslash(szFilePath); // 安全加反斜線
_stprintf_s(szFilter, _T("%s*.*"), szFilePath);
hFind = FindFirstFile(szFilter, &findData);
if (hFind == INVALID_HANDLE_VALUE) return 0;
do {
// 忽略 "." 和 ".."
if (_tcscmp(findData.cFileName, _T(".")) == 0 ||
_tcscmp(findData.cFileName, _T("..")) == 0)
continue;
TCHAR szFullPath[MAX_PATH];
_stprintf_s(szFullPath, _T("%s%s"), szFilePath, findData.cFileName);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// 遞歸處理子目錄
totalSize += GetFolderSize(szFullPath, dwFiles, dwFolders);
if (dwFolders) (*dwFolders)++;
} else {
// 累加檔案大小 (僅低 32 位,大於 4GB 檔案需用 nFileSizeHigh)
totalSize += findData.nFileSizeLow;
if (dwFiles) (*dwFiles)++;
}
} while (FindNextFile(hFind, &findData));
FindClose(hFind);
return totalSize;
}
ULONGLONG (即 DWORD64),支援 >4GB 資料夾。PathAddBackslash (需 #include 鏈接 shlwapi.lib) 或手動檢查尾部反斜線,避免 C:\FolderSub 錯誤。nFileSizeHigh:((ULONGLONG)findData.nFileSizeHigh << 32) | findData.nFileSizeLow。TCHAR/_tcscpy 等巨集,同時支援 ANSI/Unicode 建置。FindFirstFile 失敗返回 0,調用端可配合 GetLastError() 判斷權限/路徑不存在等。DWORD files = 0, folders = 0;
ULONGLONG size = GetFolderSize(_T("D:\\Projects"), &files, &folders);
CString msg;
msg.Format(_T("大小: %llu MB (%llu Bytes)\n檔案: %u\n資料夾: %u"),
size / (1024*1024), size, files, folders);
AfxMessageBox(msg);
此函數無 MFC 依賴 (僅用 Win32 API),可直接用於純 C/C++ 專案。