5

我通过查看 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 进行低级手动解析?


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

4

0 回答 0