如何手写一个文件索引工具everything(第二章)

第二章(对文件节点进行排序)

背景介绍

  • Windows平台的Everything文件查找速度非常快,优势在于利用了NTFS的USN日志,以及Windows上的文件监测机制
  • 我们也可以仿照类似原理,通过查询USN日志、监测Windows平台文件修改、使用SQLite数据库存储文件节点,并提供文件信息查询功能
    在这里插入图片描述

项目仓库

  • https://gitee.com/alanosong/MiniThing

1. 找到根目录的Reference Number

  • 在第一章中说到(https://blog.csdn.net/sunshinebooming/article/details/130183839),我们从系统USN日志中查到的所有文件节点,以父子链表的形式,通过Reference Number指定了文件之间的父子关系(目录和目录内的文件)。
  • 我们可以用递归的方式,找到每个节点的路径。而用递归,得先找到根目录的Reference Number,这样递归才有个跳出的判断依据
	// 1. Get root file node
    //  cause "System Volume Information" is a system file and just under root folder
    //  so we use it to find root folder
    std::wstring cmpStr(L"System Volume Information");
    m_rootFileNode = 0x0;

    for (auto it = m_usnRecordMap.begin(); it != m_usnRecordMap.end(); it++)
    {
        UsnInfo usnInfo = it->second;
        if (0 == usnInfo.fileNameWstr.compare(cmpStr))
        {
            m_rootFileNode = usnInfo.pParentRef;
            break;
        }
    }

    if (m_rootFileNode == 0)
    {
        std::cout << "Cannot find root folder" << std::endl;
        ret = E_FAIL;
        assert(0);
    }

2. 通过递归查找文件路径

VOID GetCurrentFilePathV2(std::wstring& path, std::wstring volName, DWORDLONG currentRef, DWORDLONG rootRef, unordered_map<DWORDLONG, UsnInfo>& recordMapAll)
{
    // 1. This is root node, just add root path and return
    if (currentRef == rootRef)
    {
        path = volName + L"\\" + path;
        return;
    }

    if (recordMapAll.find(currentRef) != recordMapAll.end())
    {
        // 2. Normal node, loop more
        std::wstring str = recordMapAll[currentRef].fileNameWstr;
        path = str + L"\\" + path;
        GetCurrentFilePathV2(path, volName, recordMapAll[currentRef].pParentRef, rootRef, recordMapAll);
    }
    else
    {
        // 3. Some system files's root node is not in current folder
        std::wstring str = L"?";
        path = str + L"\\" + path;

        return;
    }
}

你可能感兴趣的:(MiniThing,文档资料,个人开发)