如何获取磁盘中文件的大小?

Jac*_*ack 5 c winapi windows-10

如何获取磁盘中文件的大小?如 Windows 资源管理器中所示?例如,文件名具有:

size: 172 bytes (172 bytes)
size on disk: 0 bytes
Run Code Online (Sandbox Code Playgroud)

但我的申请显示:

GetDiskFreeSpace(L"C:\\" &sectorsPerCluster, &lpBytesPerSector,
            &numberOfFreeClusters, &totalNumberOfClusters));
    int TotalSize = lpBytesPerSector * ((fileLength + lpBytesPerSector - 1) / lpBytesPerSector);
    printf("fileLength = %d\n", fileLength);
    printf("TotalSize = %d\n", TotalSize);
Run Code Online (Sandbox Code Playgroud)

它输出:

fileLength = 172
TotalSize = 512
Run Code Online (Sandbox Code Playgroud)

为了正确计算文件名在磁盘中的大小,我缺少什么?

Ale*_*iev 2

也许为时已晚,但我想我已经有了答案。

\n

Windows 资源管理器也许会显示正确的信息。

\n

在NTFS上,小文件数据可以嵌入到MFT(主文件表)中。主文件表是系统文件,包含磁盘上每个文件的信息(包括其本身,是的)。该信息存储在MFT条目中,通常为1024字节。通常有文件名以及在哪里可以找到其数据。但对于较小的文件,数据可以存储在 MFT 本身中。

\n

其他文件系统也可能采用某种方式将小文件嵌入到 FS 元数据中。FAT/FAT32/exFAT 没有,但我不知道 ReFS。

\n

不将 FS 结构中的数据计为磁盘上的大小是合乎逻辑的,因为对于较大的文件名也不算数。

\n

磁盘上的大小小于大小的其他原因是压缩或稀疏文件。

\n

我不知道 Explorer 如何获取此信息,但您可以使用FSCTL_GET_RETRIEVAL_POINTERSIOCTL 获取磁盘上的文件位置,然后解析生成的RETRIEVAL_POINTERS_BUFFER. 它很复杂,但我不知道更简单的方法。我尝试过GetCompressedFileSize,但它仍然为 MFT 文件返回非零文件大小。

\n

评论中链接的文章在奖金闲谈中说

\n
\n

从 Windows 8.1 开始,磁盘大小计算包括备用数据流的大小,并尝试猜测哪些流可以存储在 MFT 中,而不将它们计入磁盘大小。(即使它们确实在磁盘上。我的意思是,如果它们 \xe2\x80\x99 不在磁盘上,那么它们在哪里?)

\n
\n

没有具体说明sort-of-kind-of-tries-to-guess 的含义,但FSCTL_GET_RETRIEVAL_POINTERS您可以得到准确的答案。

\n