日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Everything是如何搜索的

發(fā)布時(shí)間:2025/3/11 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Everything是如何搜索的 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

寫在前面

使用了Everything之后,一直對(duì)他的搜索速度感興趣,在網(wǎng)上也看了很多對(duì)其原理的揭秘,終于有空找了個(gè)源碼研究了一下,原理就是對(duì)NTFS的USN特性進(jìn)行使用。

原理

詳細(xì)解釋我參照別人家的博客來(lái)一段:

當(dāng)扇區(qū)的文件有變化時(shí),操作系統(tǒng)會(huì)往USN Journal文件中追加一條記錄,該記錄包含文件名、變化發(fā)生的時(shí)間、變化的原因等信息,而不包含變化的內(nèi)容。每一條記錄用一個(gè)64位數(shù)字標(biāo)識(shí),稱作USN(UpdateSequence Number)。微軟用每一條記錄在日志文件中的偏移作為該記錄的USN,這樣可以快速地通過(guò)USN獲取到對(duì)應(yīng)的記錄。顯而易見(jiàn),USN是遞增的,但是不連續(xù)。

所以如果想獲得磁盤的文件只需要讀取日志即可。

網(wǎng)上的源碼有很多,關(guān)于讀取日志,從日志轉(zhuǎn)換成完整路徑都不難理解,如果想自己寫一個(gè)也是可以的。

問(wèn)題

我認(rèn)為需要考慮的主要問(wèn)題:
1. 從上次讀取的位置繼續(xù)讀取;
2. 新增或刪除文件處理。

Everything 源碼超級(jí)簡(jiǎn)述

源碼仔細(xì)看并不難理解。
UsnOperator 類中,我認(rèn)為比較重要的一點(diǎn),是如何繼續(xù)讀取

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;// 如果想從上次的位置繼續(xù)讀取日志// 將lowUsn修改至上次最后一個(gè)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 監(jiān)聽(tīng)文件變化

關(guān)于電腦文件的修改監(jiān)聽(tīng),C#有相應(yīng)的類來(lái)處理,非常方便,感興趣可深挖:

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相關(guān)資料下載

參考資料

DeviceIOControl詳解-各個(gè)擊破

總結(jié)

以上是生活随笔為你收集整理的Everything是如何搜索的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。