Windows 参赛作品的数量。与其显示进度条或百分比,不如简单地显示到目前为止已处理的文件/目录的数量?问题:为什么要枚举整个MFT?这可能没有必要。这个答案可能有用:这正是我的理解(或者至少是猜测)。显示计数可能需要做些什么,但我仍然愿意接受任何可能大致接近计数的建议

Windows 参赛作品的数量。与其显示进度条或百分比,不如简单地显示到目前为止已处理的文件/目录的数量?问题:为什么要枚举整个MFT?这可能没有必要。这个答案可能有用:这正是我的理解(或者至少是猜测)。显示计数可能需要做些什么,但我仍然愿意接受任何可能大致接近计数的建议,windows,ntfs,journal,usn,Windows,Ntfs,Journal,Usn,参赛作品的数量。与其显示进度条或百分比,不如简单地显示到目前为止已处理的文件/目录的数量?问题:为什么要枚举整个MFT?这可能没有必要。这个答案可能有用:这正是我的理解(或者至少是猜测)。显示计数可能需要做些什么,但我仍然愿意接受任何可能大致接近计数的建议。您可以使用FSCTL_GET_NTFS_VOLUME_DATA来获取MFT的长度(以字节为单位)。如果将其与选定的代表性卷上的记录数进行比较,则可以估计单个MFT记录的平均长度,并使用此值计算特定卷上记录数的估计值。@HarryJohnsto


参赛作品的数量。与其显示进度条或百分比,不如简单地显示到目前为止已处理的文件/目录的数量?问题:为什么要枚举整个MFT?这可能没有必要。这个答案可能有用:这正是我的理解(或者至少是猜测)。显示计数可能需要做些什么,但我仍然愿意接受任何可能大致接近计数的建议。您可以使用FSCTL_GET_NTFS_VOLUME_DATA来获取MFT的长度(以字节为单位)。如果将其与选定的代表性卷上的记录数进行比较,则可以估计单个MFT记录的平均长度,并使用此值计算特定卷上记录数的估计值。@HarryJohnston-感谢您提供指向其他答案的链接,虽然我认为这基本上证实了我目前的做法。我认为您关于为esimate使用MFT大小的建议很好。嗨,Harry,我做了一些实验,发现了一件有趣的事情-FSCTL_ENUM_USN_DATA实际上返回MFT偏移量作为下一个“StartFileReferenceNumber”或USN(取决于您阅读的MSDN文档的哪个部分!)。该数字相对较小,与FRN或USN无关。因此,我所做的是使用FSCTL_GET_NTFS_VOLUME_数据获取MFT的大小,然后将此MFT pos视为进度指标。在我的系统(Windows 7 SP1)上,FSCTL_ENUM_USN_数据返回的数字肯定是文件引用号。我认为它总是必须的,因为这是你在下一次调用中传递给StartFileReferenceNumber的内容。你在运行什么操作系统?(如果“参考号”实际上是一个偏移量,这是有意义的,但我得到的数字不是,因为它们通常是连续的。)这是我在WinXP SP2上的工作机器。由于它不是记录在案的行为,我可能不应该依赖它,而且我猜它在7上不起作用(我将尝试)。返回的USN记录的FileReferenceNumber字段顺序不正确(尽管它们似乎是近似顺序)。在64位Windows 7上,这对我来说是一样的:FSCTL_ENUM_USN_DATA返回大约0到sizeof(MFT)/1024之间的单调值作为StartFileReferenceNumber。返回的记录数就是系统上的项目数;我无意中从文件参考号中去掉了前四个字节。请参阅我在回答中添加的附加部分。
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct NTFS_EXTENDED_VOLUME_DATA
{
    public VOLUME_ID     /**/ VolumeSerialNumber;
    public long          /**/ NumberSectors;
    public long          /**/ TotalClusters;
    public long          /**/ FreeClusters;
    public long          /**/ TotalReserved;
    public uint          /**/ BytesPerSector;
    public uint          /**/ BytesPerCluster;
    public int           /**/ BytesPerFileRecordSegment;   // <--
    public uint          /**/ ClustersPerFileRecordSegment;
    public long          /**/ MftValidDataLength;          // <--
    public long          /**/ MftStartLcn;
    public long          /**/ Mft2StartLcn;
    public long          /**/ MftZoneStart;
    public long          /**/ MftZoneEnd;
    public uint          /**/ ByteCount;
    public ushort        /**/ MajorVersion;
    public ushort        /**/ MinorVersion;
    public uint          /**/ BytesPerPhysicalSector;
    public ushort        /**/ LfsMajorVersion;
    public ushort        /**/ LfsMinorVersion;
    public uint          /**/ MaxDeviceTrimExtentCount;
    public uint          /**/ MaxDeviceTrimByteCount;
    public uint          /**/ MaxVolumeTrimExtentCount;
    public uint          /**/ MaxVolumeTrimByteCount;
};
public enum FSCTL : uint
{
    // etc...     etc...
    FILESYSTEM_GET_STATISTICS   /**/ = (9 << 16) | 0x0060,
    GET_NTFS_VOLUME_DATA        /**/ = (9 << 16) | 0x0064,  // <--
    GET_NTFS_FILE_RECORD        /**/ = (9 << 16) | 0x0068,
    GET_VOLUME_BITMAP           /**/ = (9 << 16) | 0x006f,
    GET_RETRIEVAL_POINTERS      /**/ = (9 << 16) | 0x0073,
    // etc...     etc...
    ENUM_USN_DATA               /**/ = (9 << 16) | 0x00b3,
    READ_USN_JOURNAL            /**/ = (9 << 16) | 0x00bb,
    // etc...     etc...
    CREATE_USN_JOURNAL          /**/ = (9 << 16) | 0x00e7,
    // etc...     etc...
};
// etc..

if (!GetDeviceIoControl(h_vol, FSCTL.GET_NTFS_VOLUME_DATA, out NTFS_EXTENDED_VOLUME_DATA vd))
    throw new Win32Exception(Marshal.GetLastWin32Error());

var c_mft_estimate = (vd.MftValidDataLength + (vd.BytesPerFileRecordSegment - 1))
                                                        / vd.BytesPerFileRecordSegment;
[StructLayout(LayoutKind.Sequential)]
public struct MFT_IX_REC
{
    public ushort seq;
    public ushort parent_ix_hi;
    public uint parent_ix;
};
var med = new MFT_ENUM_DATA { ... };
// ...

var rg_mftix = new MFT_IX_REC[c_mft_estimate];
// ... ready to go, without having to check whether the array needs resizing within the loop

for (int i=0; DeviceIoControl(h_vol, FSCTL.ENUM_USN_DATA, in med, out USN_RECORD usn, ...); i++)
{
    // etc..
    rg_mftix[i].parent_ix = (uint)usn.ParentId;
    // etc..
}