You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Qt C++获取Windows文件夹的Size on Disk?

Windows文件夹Size与Size on Disk的差异及Qt C++获取方法

一、Size与Size on Disk的差异原因

  • Size(大小):是文件夹内所有文件实际内容的总字节数,仅统计文件数据本身的大小,不考虑磁盘存储的物理特性。
  • Size on Disk(占用磁盘空间):是文件夹在磁盘上实际占用的物理空间,差异主要由以下因素导致:
    • 磁盘簇大小:磁盘存储以簇为最小单位,哪怕文件仅1字节,也会占用一个完整的簇空间。例如簇大小为4KB时,1字节的文件会占用4KB磁盘空间。
    • 文件压缩:NTFS等文件系统支持压缩文件,压缩后的实际占用空间会远小于文件原始大小。
    • 稀疏文件:这类文件仅为实际写入的数据分配磁盘空间,未写入的空白部分不占用物理空间。
    • 系统元数据:部分文件的系统预留空间、索引项等也会计入磁盘占用。

二、Qt C++获取Size on Disk的实现方法

Qt的QFileInfo仅能获取文件/文件夹的原始Size,要获取Size on Disk需调用Windows原生API,通过递归遍历文件夹内所有文件并计算每个文件的实际磁盘占用,最终累加得到总占用空间。

实现代码

#include <windows.h>
#include <QDir>
#include <QFileInfo>

// 计算文件夹的实际磁盘占用空间(单位:字节)
quint64 calculateFolderSizeOnDisk(const QString &folderPath) {
    quint64 totalOccupied = 0;
    QDir targetDir(folderPath);
    
    if (!targetDir.exists()) {
        return 0;
    }

    // 获取磁盘簇大小
    DWORD sectorsPerCluster, bytesPerSector;
    if (!GetDiskFreeSpaceW(reinterpret_cast<LPCWSTR>(targetDir.rootPath().utf16()), &sectorsPerCluster, &bytesPerSector, nullptr, nullptr)) {
        return 0;
    }
    const quint64 clusterSize = static_cast<quint64>(sectorsPerCluster) * bytesPerSector;

    // 遍历所有文件和子文件夹
    const QFileInfoList fileList = targetDir.entryInfoList(
        QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System
    );

    for (const QFileInfo &fileInfo : fileList) {
        if (fileInfo.isDir()) {
            // 递归计算子文件夹的占用
            totalOccupied += calculateFolderSizeOnDisk(fileInfo.absoluteFilePath());
            continue;
        }

        // 获取文件实际磁盘占用
        LARGE_INTEGER compressedSize;
        const bool getCompressedSuccess = GetCompressedFileSizeW(
            reinterpret_cast<LPCWSTR>(fileInfo.absoluteFilePath().utf16()),
            &compressedSize.HighPart
        );

        if (getCompressedSuccess) {
            // 压缩/稀疏文件直接取实际占用大小
            totalOccupied += compressedSize.QuadPart;
        } else {
            // 非压缩文件按簇大小计算占用
            const quint64 fileSize = fileInfo.size();
            const quint64 usedClusters = (fileSize + clusterSize - 1) / clusterSize; // 向上取整
            totalOccupied += usedClusters * clusterSize;
        }
    }

    return totalOccupied;
}

代码说明

  1. 获取簇大小:通过GetDiskFreeSpaceW获取目标磁盘的簇大小,这是计算非压缩文件占用的基础。
  2. 递归遍历:遍历文件夹内所有文件和子文件夹,递归处理子目录。
  3. 处理不同文件类型:
    • 对于压缩或稀疏文件,使用GetCompressedFileSizeW直接获取实际占用的磁盘空间。
    • 对于普通文件,通过文件大小除以簇大小向上取整,计算实际占用的簇总字节数。

内容的提问来源于stack exchange,提问作者qwertyuiop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:05:15