提前以编程方式确定文件“磁盘上的大小”
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)
【讨论】:
以上是关于提前以编程方式确定文件“磁盘上的大小”的主要内容,如果未能解决你的问题,请参考以下文章