首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 遞歸計算資料夾大小:Win32 API 實現

     編輯:VC 教學

函數原型

// 返回位元組數,選擇性輸出檔案/資料夾計數
ULONGLONG GetFolderSize(LPCTSTR szPath, DWORD* pdwFiles = NULL, DWORD* pdwFolders = NULL);

完整實現

ULONGLONG GetFolderSize(LPCTSTR szPath, DWORD* pdwFiles, DWORD* pdwFolders)
{
    TCHAR szFindPath[MAX_PATH];
    TCHAR szFilter[MAX_PATH];
    WIN32_FIND_DATA fd;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    ULONGLONG ullSize = 0;

    // 構建搜尋路徑:path\*
    _tcscpy_s(szFindPath, szPath);
    PathAddBackslash(szFindPath);          // 確保結尾有 \
    _tcscpy_s(szFilter, szFindPath);
    _tcscat_s(szFilter, _T("*.*"));

    hFind = FindFirstFile(szFilter, &fd);
    if (hFind == INVALID_HANDLE_VALUE) return 0;

    do {
        // 跳過 . 和 ..
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            if (!_tcscmp(fd.cFileName, _T(".")) || !_tcscmp(fd.cFileName, _T("..")))
                continue;

            // 遞歸子目錄
            TCHAR szSubPath[MAX_PATH];
            _tcscpy_s(szSubPath, szFindPath);
            _tcscat_s(szSubPath, fd.cFileName);
            ullSize += GetFolderSize(szSubPath, pdwFiles, pdwFolders);

            if (pdwFolders) (*pdwFolders)++;
        }
        else {
            // 檔案大小 (僅低 32 位,大於 4GB 需組合 nFileSizeHigh)
            ullSize += fd.nFileSizeLow;
            if (pdwFiles) (*pdwFiles)++;
        }
    } while (FindNextFile(hFind, &fd));

    FindClose(hFind);
    return ullSize;
}

關鍵 API 說明

API用途
FindFirstFile / FindNextFile枚舉目錄項目
WIN32_FIND_DATA項目資訊:屬性、檔名、大小、時間
FILE_ATTRIBUTE_DIRECTORY判斷目錄屬性
PathAddBackslashShlwapi.h,安全補齊路徑分隔符
ULONGLONG64 位無號整數,支援 >4GB 資料夾

大檔案 (>4GB) 正確累加

ULARGE_INTEGER li;
li.LowPart  = fd.nFileSizeLow;
li.HighPart = fd.nFileSizeHigh;
ullSize += li.QuadPart;

現代 C++17 替代方案

#include <filesystem>
#include <system_error>

uintmax_t GetFolderSizeModern(const std::wstring& path, std::error_code& ec)
{
    uintmax_t total = 0;
    for (auto& entry : std::filesystem::recursive_directory_iterator(path, ec)) {
        if (ec) break;
        if (entry.is_regular_file(ec)) total += entry.file_size(ec);
    }
    return total;
}

優點:跨平台、自動處理迴圈連結、例外安全、程式碼極簡。

應用場景

  • 磁碟清理工具顯示資料夾佔用空間
  • 備份軟體預估空間需求
  • 安裝程式檢查可用空間
  • 配額管理系統統計用戶用量
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved