提前以编程方式确定文件“磁盘上的大小”

Posted

技术标签:

【中文标题】提前以编程方式确定文件“磁盘上的大小”【英文标题】:Programatically determining file "size on disk" in advance 【发布时间】:2009-04-15 11:00:42 【问题描述】:

在写入之前,我需要知道给定的内存缓冲区作为磁盘(USB 棒)文件有多大。我知道除非大小落在块大小边界上,否则它可能会被四舍五入,例如一个 1 字节的文件在磁盘上占用 4096 字节。我目前正在使用 GetDiskFreeSpace() 来计算磁盘块大小,然后使用它来计算磁盘大小,如下所示:

GetDiskFreeSpace(szDrive, &dwSectorsPerCluster, 
                 &dwBytesPerSector, NULL, NULL);

dwBlockSize = dwSectorsPerCuster * dwBytesPerSector;

if (dwInMemorySize % dwBlockSize != 0)

    dwSizeOnDisk = ((dwInMemorySize / dwBlockSize) * dwBlockSize) + dwBlockSize;

else

    dwSizeOnDisk = dwInMemorySize;

这似乎工作正常,但是 GetDiskFreeSpace() 根据 MSDN 仅适用于最大 2GB 的磁盘。 GetDiskFreeSpaceEx() 不会返回相同的信息,所以我的问题是,对于 >2GB 的驱动器,我还能如何计算此信息?有没有我错过的 API 调用?我可以根据整体磁盘大小假设一些硬值吗?

【问题讨论】:

提示:这是“向上取整到下一个倍数”。您可以使用块 = (MemorySize + (BlockSize-1)) % BlockSize;短一点。 这当然假设了一个包含 N 字节的文件在相关文件系统上需要多少空间。当然,数据可能需要 N 个字节,但文件也有元数据,需要考虑在内。元数据的大小可能因文件系统而异。 【参考方案1】:

MSDN 仅声明GetDiskFreeSpace() 函数不能报告大于 2GB 的卷大小。它适用于检索每个集群的扇区和每个扇区的字节数,我自己用它来编写看起来非常相似的代码;-)

但如果您还需要磁盘容量,则需要额外致电GetDiskFreeSpaceEx()

【讨论】:

这将教会我更仔细地阅读文档!我刚刚尝试了我硬盘上的代码,它似乎工作得很好。谢谢。【参考方案2】:

磁盘上文件的大小是一个模糊的概念。在 NTFS 中,文件由一组数据元素组成。您主要考虑的是“未命名的数据流”。这是一个文件的属性,如果它很小,可以与目录条目中的其他属性一起打包。 Apparently,您可以在目录条目本身中存储最多 700-800 字节的数据流。因此,您假设的 1 字节文件将与 0 字节或 700 字节文件一样大。

另一个影响是文件压缩。这将使磁盘上的大小可能小于内存中的大小。

【讨论】:

我还将稀疏文件添加到例外列表中。 稀疏文件不会自发出现,你必须有意识地创建它们。 OTOH,我描述的属性打包总是发生,如果目录(或磁盘)被压缩,文件压缩就会发生。【参考方案3】:

您应该能够使用 DeviceIoControl 函数获取此信息,并且 DISK_GEOMETRY_EX。它将返回一个结构,其中包含我认为您正在寻找的信息

http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms809010.aspx

【讨论】:

【参考方案4】:

在动作脚本中!

var size:Number = 19912;
var sizeOnDisk:Number = size;
var reminder:Number = size % (1024 * 4);
if(reminder>0)
    sizeOnDisk = size + ((1024 * 4)- reminder)

trace(size)
trace(sizeOnDisk)

【讨论】:

以上是关于提前以编程方式确定文件“磁盘上的大小”的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式确定 SQL Server Compact sdf 文件的大小

如何获取目录C ++的磁盘大小

Windows 8中非零文件的“磁盘大小”为零?

有没有办法在磁盘上批量输出文件大小?

以编程方式确定 C++ 数组的大小?

如何在 C# 中获取文件大小?