加速NTFS文件枚举(使用FSCTL_ENUM_USN_DATA和NTFS MFT / USN日志)

时间:2017-07-19 01:43:45

标签: c++ performance winapi ntfs ntfs-mft

我通过查看NTFS MFT / USN期刊来枚举NTFS硬盘分区的文件:

HANDLE hDrive = CreateFile(szVolumePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
DWORD cb = 0;

MFT_ENUM_DATA med = { 0 };
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = MAXLONGLONG;      // no change in perf if I use med.HighUsn = ujd.NextUsn; where "USN_JOURNAL_DATA ujd" is loaded before

unsigned char pData[sizeof(DWORDLONG) + 0x10000] = { 0 }; // 64 kB

while (DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL))
{
        med.StartFileReferenceNumber = *((DWORDLONG*) pData);    // pData contains FRN for next FSCTL_ENUM_USN_DATA

       // here normaly we should do: PUSN_RECORD pRecord = (PUSN_RECORD) (pData + sizeof(DWORDLONG)); 
       // and a second loop to extract the actual filenames
       // but I removed this because the real performance bottleneck
       // is DeviceIoControl(m_hDrive, FSCTL_ENUM_USN_DATA, ...)
}

它有效,它比通常的FindFirstFile枚举技术快得多。但我看到它还不是最佳

  • 在我的700k文件C:\上,需要21秒。 (此措施必须在重新启动后完成,否则,由于缓存而不正确)。

  • 我见过另一个索引软件(不是Everything,另一个)能够在<中找到C:\ 5秒(在Windows启动后测量),无需读取.db文件中的预先计算的数据库(或其他类似的技巧,可以加快速度!)。该软件不使用FSCTL_ENUM_USN_DATA,而是使用低级NTFS解析。

我试图提高效果

问题

是否可以提高效果DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)

或是提高性能以进行NTFS的低级手动解析的唯一方法?

注意:根据测试,在这些{700}文件的DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)期间要读取的总大小 84MB。 21秒读取84MB只有4 MB /秒(我确实有一个SSD!)。可能还有一些提升绩效的空间,你不这么认为吗?

0 个答案:

没有答案