Everything是如何搜索的

写在前面

使用了Everything之后,一直对他的搜索速度感兴趣,在网上也看了很多对其原理的揭秘,终于有空找了个源码研究了一下,原理就是对NTFS的USN特性进行使用。

原理

详细解释我参照别人家的博客来一段:

当扇区的文件有变化时,操作系统会往USN Journal文件中追加一条记录,该记录包含文件名、变化发生的时间、变化的原因等信息,而不包含变化的内容。每一条记录用一个64位数字标识,称作USN(UpdateSequence Number)。微软用每一条记录在日志文件中的偏移作为该记录的USN,这样可以快速地通过USN获取到对应的记录。显而易见,USN是递增的,但是不连续。

所以如果想获得磁盘的文件只需要读取日志即可。

网上的源码有很多,关于读取日志,从日志转换成完整路径都不难理解,如果想自己写一个也是可以的。

问题

我认为需要考虑的主要问题:

  1. 从上次读取的位置继续读取;
  2. 新增或删除文件处理。

Everything 源码超级简述

源码仔细看并不难理解。
UsnOperator 类中,我认为比较重要的一点,是如何继续读取

public List<UsnEntry> GetEntries()
{var result = new List<UsnEntry>();UsnErrorCode usnErrorCode = this.QueryUSNJournal();if (usnErrorCode == UsnErrorCode.SUCCESS){MFT_ENUM_DATA mftEnumData = new MFT_ENUM_DATA();mftEnumData.StartFileReferenceNumber = 0;// 如果想从上次的位置继续读取日志// 将lowUsn修改至上次最后一个UsnEntry.Usn即可mftEnumData.LowUsn = 0;mftEnumData.HighUsn = this.ntfsUsnJournalData.NextUsn;int sizeMftEnumData = Marshal.SizeOf(mftEnumData);IntPtr ptrMftEnumData = GetHeapGlobalPtr(sizeMftEnumData);Marshal.StructureToPtr(mftEnumData, ptrMftEnumData, true);int ptrDataSize = sizeof(UInt64) + 10000;IntPtr ptrData = GetHeapGlobalPtr(ptrDataSize);uint outBytesCount;while (false != Win32Api.DeviceIoControl(this.DriveRootHandle,UsnControlCode.FSCTL_ENUM_USN_DATA,ptrMftEnumData,sizeMftEnumData,ptrData,ptrDataSize,out outBytesCount,IntPtr.Zero)){IntPtr ptrUsnRecord = new IntPtr(ptrData.ToInt32() + sizeof(Int64));while (outBytesCount > 60){var usnRecord = new USN_RECORD_V2(ptrUsnRecord);result.Add(new UsnEntry(usnRecord));ptrUsnRecord = new IntPtr(ptrUsnRecord.ToInt32() + usnRecord.RecordLength);outBytesCount -= usnRecord.RecordLength;}Marshal.WriteInt64(ptrMftEnumData, Marshal.ReadInt64(ptrData, 0));}Marshal.FreeHGlobal(ptrData);Marshal.FreeHGlobal(ptrMftEnumData);}return result;
}

使用 FileSystemWatcher 监听文件变化

关于电脑文件的修改监听,C#有相应的类来处理,非常方便,感兴趣可深挖:

FileSystemWatcher _watcher = new FileSystemWatcher(@"J:\", "*.*");
_watcher.Created += new FileSystemEventHandler(OnProcess);
_watcher.Changed += new FileSystemEventHandler(OnProcess);
_watcher.Deleted += new FileSystemEventHandler(OnProcess);
_watcher.Renamed += new RenamedEventHandler(OnFileRenamed);
_watcher.IncludeSubdirectories = true;
_watcher.EnableRaisingEvents = true;

下载

Everything相关资料下载

如果没有积分,也可以关注我获取哟~
hi

参考资料

DeviceIOControl详解-各个击破

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫话:如何给女朋友解释String对象是不可变的?

String的不变性String在Java中特别常用&#xff0c;相信很多人都看过他的源码&#xff0c;在JDK中&#xff0c;关于String的类声明是这样的&#xff1a;public final class String implements java.io.Serializable, Comparable<String>, CharSequence { }可以看到&#…

XenServer 6.5实战系列之十一:Install Update For XenServer 6.5

为了保证XenServer主机的安全及功能的更新&#xff0c;在企业环境中我们需要定期的到Citrix官网或通过XenCenter进行下载和更新。今天我们会从在线和离线两种不同的方法进行Update的安装。更新补丁之前请务必阅读对应Update的相关资料、注意事项和做好备份。1. 离线安装更新在…

机器学习 属性_属性关系文件格式| 机器学习

机器学习 属性Today, we will be looking at the use of attribute relation file format for machine learning in java and we would be writing a small java code to convert the popularly used .csv file format into the arff (Attribute relation file format). This f…

C#标记废弃方法

一、普通用法 在C#中&#xff0c;如果一个方法我们不再使用&#xff0c;我们可以将其标记为“废弃”的方法&#xff0c;只需要在方法前&#xff0c;加一个[Obsolete]即可&#xff1b; [Obsolete] public void BiuBiuBiu(){// 嘿嘿嘿 }废弃方法并非不能使用&#xff0c;而是在…

阿里二面一问MySQL就开始野了,抓着底层原理不撒手啊!

最近项目增加&#xff0c;缺人手&#xff0c;面试不少&#xff0c;但匹配的人少的可怜。跟其他组的面试官聊&#xff0c;他也抱怨了一番&#xff0c;说候选人有点儿花拳绣腿&#xff0c;回答问题不落地&#xff0c;拿面试最常问的MySQL来说&#xff0c;并不只是懂“增删改查”、…

[转]“Ceph浅析”系列之(—)—Ceph概况

转载自&#xff1a;http://yizhaolingyan.net/?p11本文将对Ceph的基本情况进行概要介绍&#xff0c;以期读者能够在不涉及技术细节的情况下对Ceph建立一个初步印象。2.1 什么是Ceph&#xff1f;Ceph的官方网站Ceph.com上用如下这句话简明扼要地定义了Ceph&#xff1a;“Ceph…

关于C#监视剪贴板信息

##1、常规方法 在C#中&#xff0c;有一个常规检测剪贴板的方法&#xff0c;用的是 System.Windows.Forms.Clipboard&#xff1b; 使用起来很简单&#xff0c;代码如下&#xff1a; /// <summary> /// 设置剪贴板的文本内容 /// </summary> /// <param name&qu…

图解Java中的18 把锁!

乐观锁和悲观锁独占锁和共享锁互斥锁和读写锁公平锁和非公平锁可重入锁自旋锁分段锁锁升级&#xff08;无锁|偏向锁|轻量级锁|重量级锁&#xff09;锁优化技术&#xff08;锁粗化、锁消除&#xff09;乐观锁和悲观锁悲观锁悲观锁对应于生活中悲观的人&#xff0c;悲观的人总是想…

在CSS中使用not:first-child选择器

Introduction: 介绍&#xff1a; Well, selectors are a very common term to deal with while we are developing a website or web page. You might know quite a few of them and might as well be implementing them. You might also have noticed that all the selectors…

linux/unix 段错误捕获【续】

本文为“在C/C中捕获段错误&#xff0c;打印出错的具体位置”的续篇&#xff0c;进一步解决涉及动态链接库的情况。背景知识&#xff1a;linux/unix下动态链接库的基本原理/proc/pid/maps文件的基本格式动态链接库&#xff1a;在进程执行过程中动态加载&#xff0c;进程间可以共…

Spring为什么建议构造器注入?

来源 | juejin.cn/post/6844904056230690824作者 | Richard_Yi本文的内容主要是想探讨我们在进行 Spring 开发过程当中&#xff0c;关于依赖注入的几个知识点&#xff0c;具体内容如下&#xff1a;Autowired, Resource, Inject 三个注解的区别当你在使用Autowired时&#xff0…

一文玩转 EhCache 缓存框架!

Ehcache 介绍EhCache 从 Hibernate 发展而来&#xff0c;是一个纯Java的进程内缓存框架&#xff0c;具有快速、精干等特点。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存&#xff0c;Java EE和轻量级容器。它具有内存和磁盘存储&#xff0c;缓存加载器&#x…

avr uart打印_AVR | 在16x2 LCD上打印HELLO WORLD

avr uart打印We would learn the connection to the LCD first as the connections is a bit complex and here we are using an 8-bit LCD. 我们将首先学习到LCD的连接&#xff0c;因为连接有点复杂&#xff0c;这里我们使用的是8位LCD 。 Simulation 模拟 Explanation 说明…

linux中lvm的缩减

问题提出&#xff1a;服务器硬盘做成了lvm&#xff0c;但是/home目录空间较大&#xff0c;于是想缩减一下&#xff0c;分配给其他目录。实验环境&#xff1a;操作系统&#xff1a;redhat企业版&#xff0c;硬盘已经做成了lvm。问题解决&#xff1a;操作前的注意事项&#xff1a…

SpringBoot 过滤器、拦截器、监听器对比及使用场景!

来源 | blog.csdn.net/qq_38020915/article/details/116431612作者 | dingwen_blog一、关系图理解二、区别1.过滤器过滤器是在web应用启动的时候初始化一次, 在web应用停止的时候销毁可以对请求的URL进行过滤, 对敏感词过滤挡在拦截器的外层实现的是 javax.servlet.Filter 接口…

Jenkins Build Radiators(构建发射源)

为什么80%的码农都做不了架构师&#xff1f;>>> information radiators&#xff08;信息发射源&#xff09;的概念通常被用在敏捷的圈子里。 据敏捷专家Alistair Cockburn所说&#xff1a; 一个信息发射源是一个贴在一个地方的显示器&#xff0c;当人们工作或路过时…

线程池是如何重复利用空闲的线程来执行任务的?

来源&#xff1a;blog.csdn.net/anhenzhufeng/article/details/88870374在Java开发中&#xff0c;经常需要创建线程去执行一些任务&#xff0c;实现起来也非常方便&#xff0c;但如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c…

C# 将程序添加开机启动的三种方式

前言 最近在研究程序随系统启动&#xff0c;发现在 win7 上因为权限的问题&#xff0c;写注册表的时候总是会出现问题&#xff0c;写不进去导致的不能自动启动&#xff0c;随后决定仔细的看一看这方面的问题。 查资料过程中主要发现有三种方式可以添加到启动&#xff0c;分别…

SpringBoot 中的 3 种条件装配!

一、介绍在实际的项目开发中&#xff0c;我们往往需要根据不同的环境做出不同的配置&#xff0c;例如&#xff1a;在开发环境下&#xff0c;我们会使用内存数据库以便快速启动服务并进行开发调试&#xff0c;在test环境、生产环境&#xff0c;会使用对应环境的数据库。如果我们…

图说 mysql 事务隔离级别

转载于:https://blog.51cto.com/kingbox/1657916