开源2010年,自己在学习 Lucene 时开发的一款桌面文件搜索工具,这么多年过去了,代码一直静静存放在自己的硬盘上,与其让其沉睡,不如分享出来。

这款工具带有明显的模仿 Everything 的痕迹。事实上这是当时某项课程的作业,而那个时候刚好发现了 Eveything 这款神奇的工具,出于想探究其原理,就着手做了一款与其类似的工具,但是最后的结果却是令人不满意的,因为差距仍然是很大。

就比如 Everything 能够实时监测 NTFS 文件的变化(据说是监测 NTFS 的日志)并自动更新索引,而我却需要手动来更新。

虽然这不是一款另我十分满意的作品,但希望其中某些部分能够帮到有需要的人。这里还要感谢共同完成的杨一和江边串串香。

代码开源在 Github 上,地址在这里。

为什么选择 Lucene?

  1. Lucene 是最著名的全文检索引擎的核心库,使用 Lucene 可以让搜索出来的结果按匹配程度排序。
  2. Lucene 有很多版本的实现,Java,C#,Python。
  3. 用数据库的模糊搜索也可以实现,但是效果和速度跟 Lucene 还是有差距。

关于 Lucene 的一些资料可以参考车东的笔记。

功能

实现对桌面文件名、MP3 文件 Tag 信息(歌手,专辑,流派,...)的快速检索。

前提:需要先对文件建立索引。

分词

默认情况下使用中文的分词是对词进行切分,比如:

这是文件名 -> 这是|文件名

为了实现对文件名的模糊搜索,需要自定义一个自己的分词,分词效果是对所有的字都进行切分:

这是文件名 -> 这|是|文|件|名

特别指出,Lucene 可以自定义分词,这里就不展开介绍。

在 Lucene.Net.Analysis 中添加一个自己的 MyAnalyzer

//文件:Lucene/Net/Analysis/MyAnalyzer/MyAnalyzer.cs
using System;
using System.Collections.Generic;
using System.Text;
using Lucene.Net.Analysis;
using System.IO; namespace Lucene.Net.Analysis.MyAnalyzer
{
public class MyAnalyzer : Analyzer
{
public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader)
{
TokenStream result = new MyTokenizer(reader);
return result;
} public override TokenStream ReusableTokenStream(System.String fieldName, System.IO.TextReader reader)
{
Tokenizer tokenizer = (Tokenizer)GetPreviousTokenStream();
if (tokenizer == null)
{
tokenizer = new MyTokenizer(reader);
SetPreviousTokenStream(tokenizer);
}
else
tokenizer.Reset(reader);
return tokenizer;
}
}
}
//文件:Lucene/Net/Analysis/MyAnalyzer/MyTokenizer.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Lucene.Net.Analysis; using Token = Lucene.Net.Analysis.Token;
using Tokenizer = Lucene.Net.Analysis.Tokenizer; namespace Lucene.Net.Analysis.MyAnalyzer
{
public class MyTokenizer : Tokenizer
{
public MyTokenizer(System.IO.TextReader input) : base(input)
{ } private int start = 0;
private int length = 0;
private const int IO_BUFFER_SIZE = 256;
private char[] ioBuffer = new char[IO_BUFFER_SIZE]; public override Token Next(Token token)
{
token.Clear();
if (start == 0)
{
length = input.Read((System.Char[])ioBuffer, 0, ioBuffer.Length);
if (length <= 0)
return null;
} if (start == length)
return null;
token.SetTermBuffer(ioBuffer, start, 1); start++;
token.termBuffer[0] = System.Char.ToLower(token.termBuffer[0]);
return token;
} public override void Reset(System.IO.TextReader input)
{
start = 0;
length = 0;
}
}
}

相关注意事项

  1. 由于需要访问系统注册表,来根据文件扩展名获取图标,因此启动的时候需要管理员权限,同时在VS上开发的时候,也相应需要用管理员权限打开VS。
  2. 建立索引的时候,使用了三个线程来处理文件索引操作:分扫描磁盘文件,处理扫描获取的文件数据,将文件信息加入到索引中。它们之间使用队列来传递文件信息,如果运行时线程的速度不一致,就会出现队列有大量未处理的数据,导致诡异的内存占用升到非常高。这在其他同学的电脑上测试时有出现过。(当时使用多线程,是为了在等待IO时,顺便创建索引)

基于 Lucene 的桌面文件搜索的更多相关文章

  1. Apache Solr采用Java开发、基于Lucene的全文搜索服务器

    http://docs.spring.io/spring-data/solr/ 首先介绍一下solr: Apache Solr (读音: SOLer) 是一个开源.高性能.采用Java开发.基于Luc ...

  2. 一种安全云存储方案设计(下)——基于Lucene的云端搜索与密文基础上的模糊查询

    一种安全的云存储方案设计(未完整理中) 一篇老文了,现在看看错漏颇多,提到的一些技术已经跟不上了.仅对部分内容重新做了一些修正,增加了一些机器学习的内容,然并卵. 这几年来,云产品层出不穷,但其安全性 ...

  3. 8 个基于 Lucene 的开源搜索引擎推荐

    Lucene是一种功能强大且被广泛使用的搜索引擎,以下列出了8种基于Lucene的搜索引擎,你可以想象它们有多么强大. 1. Apache Solr Solr 是一个高性能,采用Java5开发,基于L ...

  4. Lucene5.5.4入门以及基于Lucene实现博客搜索功能

    前言 一直以来个人博客的搜索功能很蹩脚,只是自己简单用数据库的like %keyword%来实现的,所以导致经常搜不到想要找的内容,而且高亮显示.摘要截取等也不好实现,所以决定采用Lucene改写博客 ...

  5. 基于Solr的空间搜索

    如果需要对带经纬度的数据进行检索,比如查找当前所在位置附近1000米的酒店,一种简单的方法就是:获取数据库中的所有酒店数据,按经纬度计算距离,返回距离小于1000米的数据. 这种方式在数据量小的时候比 ...

  6. WebGIS中解决使用Lucene进行兴趣点搜索排序的两种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 目前跟信息采集相关的一个项目提出了这样的一个需求:中国银行等 ...

  7. WebGIS中兴趣点简单查询、基于Lucene分词查询的设计和实现

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 兴趣点查询是指:输入框中输入地名.人名等查询信息后,地图上可 ...

  8. Apache Lucene(全文检索引擎)—搜索

    目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...

  9. 基于lucene的案例开发:查询语句创建PackQuery

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44656141 http://www.llwjy.com/blogdetail/1 ...

随机推荐

  1. 简话Angular 00 为什么要学Angular

    一句话: 现在不学Angular的结局,就和5年前不学JQuery一样! 谁学谁知道,早学早进阶! 1. JQuery vs Javascipt 问两个问题: 1) 你用过JQuery吗?当然! 2) ...

  2. WebApi用Post的方式提交Json时,获取不到值或不进对应方法的问题

    又是一个通宵,终于搞明白了. 被WebApi坑得好惨. 之前用各种方法Post上来,有时可以读到结构,但没值,有时直接就是一个Null,有时连方法都没进就跑了,只是来控制器里看了一下…… 最后好友说还 ...

  3. android 笔记一

    1.Fragment创建extents FragmentView rootView = inflater.inflate(R.layout.fragment_main, container, fals ...

  4. HDU 6153 A Secret(扩展kmp)

    A Secret Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)Total ...

  5. 升级安装windows8.1以后windowsphone8不能启动虚拟机的办法

    如果之前在的虚拟机是OK的话,VS2012需要安装update3补丁才可以. 下载地址:http://download.microsoft.com/download/D/4/8/D48D1AC2-A2 ...

  6. tintColor 与 UIImage.renderingMode 渲染

    在iOS7中,UIView新增了一个属性tintColor.这是一个UIColor,被使用在UIView中改变应用程序的外观的.默认tintColor的值为nil,这表示它将会运用父视图层次的颜色来进 ...

  7. PHPCMS v9 二次开发_验证码结合Session开发

    本文主要讲解了在V9中使用v9自带验证码并且需要使用session的情况下,多种问题的解决.:).如有问题或者更好的解决办法,希望不吝赐教. 1.前端调用验证码 pc_base::load_sys_c ...

  8. java定时器无法自动注入的问题解析(原来Spring定时器可以这样注入service)

    近些日子在做一个项目,在项目中需要用到spring的定时任务,但是在操作数据库的时候发现总是不能正确的进行数据的插入,经过查看才发现:是因为service层不能够通过普通的方法注入到action,所以 ...

  9. threejs通过射线Ray获取指定的点

    例:获取cube方向上的面的中点坐标(该cube默认方向为(0,1,0)) (中心点向cube quaternion 方向上发射射线,与正前方的面相交的点即为目标点; 由于ray只支持box和face ...

  10. java编程排序之自定义类型的集合,按业务需求排序

    自定义引用类型放入集合中,按实际业务需求进行排序的两种思路 第一种思路: (1)自定义实体类实现java.lang.Comparable接口,重写public int compareTo(Object ...