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

2024-01-09

我通过查看 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:\在 FSCTL_ENUM_USN_DATA,而是低级 NTFS 解析。

我为提高性能所做的努力:

  • 使用另一个标志打开文件,例如FILE_FLAG_SEQUENTIAL_SCAN, FILE_FLAG_RANDOM_ACCESS, or FILE_FLAG_NO_BUFFERING:相同的结果:读取 21 秒

  • 看着估计 NTFS 卷上的 USN 记录数 https://stackoverflow.com/questions/11336390/estimate-the-number-of-usn-records-on-ntfs-volume, 为什么在 VB.NET 中使用 DeviceIoControl 进行文件枚举比在 C++ 中更快? https://stackoverflow.com/questions/27393985/why-file-enumeration-using-deviceiocontrol-is-faster-in-vb-net-than-in-c我已经深入研究了它们,但它没有提供这个实际问题的答案。

  • 测试另一个编译器:MinGW64 而不是 VC++ Express 2013:相同的性能结果,没有差异

  • 在 VC++ 上,我已经切换到Release代替Debug:还有其他项目属性/选项可以加快程序速度吗?

Question:

是否可以提高性能DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)?

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


注:根据测试,这些期间读取的总大小DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, ...)对于我的 700k 文件来说是only84MB。读取 84MB 需要 21 秒,速度仅为 4 MB/秒(而且我确实有 SSD!)。性能可能还有一些改进的空间,您不这么认为吗?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • window 对象在 Chrome 和 IE 中表现奇怪

    考虑以下 HTML 示例 div div 以及以下脚本 var about function window document use strict var methods methods init function Do things he
  • 如何在 R 中一起绘制两个直方图?

    我正在使用 R 并且有两个数据框 胡萝卜和黄瓜 每个数据框都有一个数字列 列出所有测量的胡萝卜 总计 100k 胡萝卜 和黄瓜 总计 50k 黄瓜 的长度 我希望在同一个图上绘制两个直方图 胡萝卜长度和黄瓜长度 它们重叠 所以我想我还需要一
  • django-tastypie PATCH 给了我一个“400(错误请求)”

    我正在 Apache 上运行一个 Django 站点 该站点以 Nginx 实例为前端 为我的静态媒体提供服务 我通过 django tastypie 将 API 暴露给需要修补字段的模型 当我进行本地测试 通过 django runser
  • 数组衰减为指针的异常?

    我在许多帖子中看到 在大多数情况下 数组名称会退化为指针 我可以知道在什么情况 表达式下数组名称不会衰减为指向其第一个元素的指针吗 Sure 在C99中存在三种基本情况 即 当它是争论的时候 地址 运算符 当它是争论的时候sizeof操作员
  • 如何使用 libphonenumber 以国际格式格式化电话号码。

    In the 文档 https github com googlei18n libphonenumber由Github上的libphonenumber提供 有一个demo https rawgit com googlei18n libpho
  • view.getId() 在 OnItemClickListener 中返回错误的 id

    在我的应用程序中 我有一个包含一些图像的图库 当用户选择图像时 我想以某种方式检索所选图像的 id getId 返回的 int 为 1 为什么我无法获取所选图像的系统 ID gallery setOnItemClickListener ne
  • 使用左连接的 LINQ orderby FK

    我有以下代码 from categories in context SCT Categories join categoryOrders in context SCT CategoryOrders on categories ID equa
  • 如何在 Firefox 中正确渲染@font-face?

    我正在尝试对 Chrome Safari Firefox 和 IE 使用 font face 对于 IE 我什至不知道该怎么做 但对于其他浏览器 我希望 font face 部分能够工作 这是我用过的 font face font fami
  • ruby 从数组中删除一个元素

    我想从数组中按值删除 仅一个 元素 例子 x 1 2 3 2 x remove 2 result x 1 3 但是 我想得到 1 3 2 thanks 正如 7urkm3n在评论中提到的 你可以使用x delete at删除第一个出现的位置
  • Git hooks - 从远程存储库传播?

    我目前正在寻求将现有的 SVN 存储库转换为 git 然后在允许推送之前使用 Reviewboard 进行审核 我最近才开始使用 git 而且远不是这方面的专家 但是我想做的是有一个预推送钩子 它运行 后审查 以将更改提交到 ReviewB
  • 为什么不允许调用main函数?

    C 03 3 6 1 3 不得在程序中使用 main 函数 3 2 我想知道为什么这条规则存在 有人知道如果使用 main 会出现问题的任何系统 实现吗 附 1 我知道这个词的定义used 2 我知道有一些简单的解决方法 例如从 main
  • 找不到提供者 docker - Vagrant

    每当我跑步时vagrant up provider docker 我收到此错误消息 The provider docker could not be found but was requested to back the machine d
  • 为什么 gcc 不会对 int 和 char 产生类型不匹配警告?

    为什么在 gcc 中编译以下代码不会产生任何类型不匹配警告 1属于类型int and f 期望类型char void f char c int main void f 1 return 0 即使我们明确指定类型 也不会出现警告 void f
  • 混合 fdopen() 和 open() -> 错误的文件描述符

    int source open hi O CREAT O RDONLY int dest open resultfile O CREAT O RDWR O TRUNC FILE source1 fdopen source r FILE de
  • 合并(与拆分相反)r 中的行对

    我有如下的专栏 每列有两对 每对带有后缀 a 和 b 例如 col1a col1b colNa colNb 等 直到文件末尾 gt 50000 mydataf lt data frame Ind 1 5 col1a sample c 1 3
  • ROC 函数错误“预测变量必须是数字或有序的。”

    我无法让 ROC 函数正常工作 收到错误 预测器必须是数字或有序的 我浏览了其他帖子 但没有解决我的问题 非常感谢任何帮助 Get data flying dget https www math ntnu no emner TMA4268
  • SQL - 查找两列相同的所有实例

    所以我有一个简单的桌子来容纳comments from a user与特定博客相关的post id user post id comment 0 email protected cdn cgi l email protection 1001
  • MySQL 不允许对 DATETIME 字段执行 ON UPDATE CURRENT_TIMESTAMP

    我看过很多相关问题 但我无法指出这个具体问题 我有一个 MySQL 表 其中包含 TIMESTAMP 用于创建字段的时间 和 DATETIME 用于每次更新字段的时间 它看起来像这样 CREATE TABLE vis ID BIGINT P
  • sqlite 在日期中添加天数

    我正在尝试编写一个 sqlite 语句 该语句从表中返回一个日期 并从另一列添加了一定的天数 日期存储为YYYY MM DD HH mm ss以及整数形式的天数 我有 SELECT strftime Y m d H M S strftime
  • 加速 NTFS 文件枚举(使用 FSCTL_ENUM_USN_DATA 和 NTFS MFT / USN 日志)

    我通过查看 NTFS MFT USN 日志来枚举 NTFS 硬盘分区的文件 HANDLE hDrive CreateFile szVolumePath GENERIC READ FILE SHARE READ FILE SHARE WRIT