我最近在一个程序上玩硬链接,该程序在其目录中的所有位置复制文件,删除所有重复项并用硬链接替换它们。我把它弄好了。我理解硬链接的工作方式,它只是磁盘上数据本身的另一个引用。因此,如果我要从创建的硬链接访问数据,它看起来会一样。
问题在于找到所使用的实际磁盘空间量,这是验证确实节省空间的问题之一。换句话说,如果要从一个12K文件开始,创建该文件的硬链接,然后在资源管理器中选择它们,它将显示为磁盘上使用的24K,而不是真正应该的12K。
我知道我可以在进程前后查询磁盘上的可用空间然后进行比较。但这是初步评估,事后很难核实。我也知道我可以使用GetFileInformationByHandle来查明相关文件是否有多个引用。
所以这里有什么想法?我是否必须为每个文件调用GetFileInformationByHandle,记录所有数据,然后删除具有重复索引引用的文件,以准确查看实际使用的磁盘空间量?或者有更简单的方法来实现这一目标吗?
答案 0 :(得分:1)
做到这一点。维护一组(dwVolumeSerialNumber,nFileIndexHigh,nFileIndexLow)三元组。每次遇到文件时,请检查您之前是否看过它(即,它的三元组是否已经在您的设置中)。如果是这样,那就跳过它。如果没有,则将其文件大小添加到总计中,并将其信息插入到集合中。
不幸的是,这意味着你必须打开每个文件。链接计数未保留在目录信息中,因此FindFirstFile
无法将其提供给您。您需要GetFileInformationByHandle
,这需要一个句柄。
您可能希望阅读Raymond Chen's article on the topic;除了可以应用于您的应用程序的硬链接之外,它还提到了几个极端情况,包括重新分析点,群集舍入和备用数据流。
您可以尝试通过仅跟踪链接数大于1的文件来减少维护集所需的工作量。只有一个链接的文件不应在目录遍历中多次出现。假设您只能看到每个目录一次。重新分析点和结点可能会使假设无效,因此如果您尝试减小“看到的文件”集的大小,则还需要跟踪已经看过的目录。