如何用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()), §orsPerCluster, &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; }
代码说明
- 获取簇大小:通过
GetDiskFreeSpaceW获取目标磁盘的簇大小,这是计算非压缩文件占用的基础。 - 递归遍历:遍历文件夹内所有文件和子文件夹,递归处理子目录。
- 处理不同文件类型:
- 对于压缩或稀疏文件,使用
GetCompressedFileSizeW直接获取实际占用的磁盘空间。 - 对于普通文件,通过文件大小除以簇大小向上取整,计算实际占用的簇总字节数。
- 对于压缩或稀疏文件,使用
内容的提问来源于stack exchange,提问作者qwertyuiop
相关产品推荐
相关产品推荐

