当第一次使用 USN 日志时,必须使用 FSCTL_ENUM_USN_DATA 控制代码枚举卷的整个 USN 记录集。这通常是一个漫长的操作。
有没有办法在运行卷之前估计卷上的记录数,以便显示进度?
我猜整个卷的 USN 数据是从 MFT 生成的,每个文件一条记录(大约)。因此,估计 MFT 中事件文件数量的方法或许可行。
最佳答案
您可以使用 FSCTL_GET_NTFS_VOLUME_DATA 获取 MFT 的字节长度。如果您将此与选定的代表性卷上的记录数进行比较,则可以估计单个 MFT 记录的平均长度,并使用它来计算特定卷上记录数的估计值。
因为 MFT 包含(例如)每个文件的安全信息,平均长度会因卷而异,所以我认为您只能获得数量级的准确性,但它可能已经足够好了在大多数情况下。
另一种方法是假设文件引用编号线性增加,这大致是正确的。您可以使用 FSCTL_ENUM_USN_DATA 来查明是否有任何文件的引用编号高于特定猜测;您只需猜测不超过 128 次即可确定实际的最大引用数。这至少会给你一个在任何给定点 0 到 100 之间的完成百分比,它不会完全统一,但进度条永远不会。 :-)
附加:
仔细观察,在 Windows 7 x64 上,FSCTL_ENUM_USN_DATA(在第一个 USN_RECORD 结构之前返回的四字)返回的“下一个 ID”字段毕竟不是文件引用号,而是文件记录段号。因此,正如您观察到的那样,返回的最后一个 ID 号乘以 BytesPerFileRecordSegment (1024) 等于 MftValidDataLength。
文件引用编号似乎由两部分组成。低六字节包含文件记录段号。从每个请求返回的第一条记录总是有一个 FRN,其段号与馈入 StartFileReferenceNumber 的“下一个 ID”相同,除了当 StartFileReferenceNumber 为零时的第一次调用。高两个字节包含未指定的附加信息,这些信息永远不会为零。
FSCTL_ENUM_USN_DATA 似乎接受文件记录段号(在这种情况下前两个字节为零)或文件引用号(在这种情况下前两个字节不为零)。
一个奇怪的问题是我找不到具有相同记录段号的两条记录。这表明每个文件记录在 MFT 中至少使用 1K,这似乎不合理。
无论如何,结果是将“下一个 id”乘以 BytesPerFileRecordSegment 并将其除以 MftValidDataLength 以获得完成的百分比可能是明智的,只要您在返回无意义的结果时优雅地应对即可。
关于windows - 估计 NTFS 卷上的 USN 记录数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11336390/