易搜

易搜

1.简介
仿照桌面工具Everything,基于Java语言开发的命令行搜索工具。

2.意义

  • 解决了Windows下的搜索盘符限制,可以在整个文件系统搜索;
  • 可以跨平台使用,比如在Windows、Linux系统;

3.功能

  • 文件名模糊检索: 比如用户检索"报告",可以检索出本系统中所有含有“报告”的文件;
  • 指定文件类型:文件类型支持文档类(doc),二进制类(bin),图片类(img),其他(other),会检索出用户需要的文件类型
  • 用户友好:用户可以指定检索的目录和排除的目录以及检索文件的数量和排序策略,否则就是默认值;
  • 文件监听:当本地文件新增或删除,数据库会有相应的修改

4.技术

  • Java(基本语法、文件操作、多线程)
  • Database(嵌入式H2数据库)
  • JDBC编程
  • Lombok库(IDEA安装Lombok插件)
  • 文件系统监听(Apache Commons IO)

5.实现
在这里插入图片描述
5.1 H2数据库

  • 开源的Java语言编写的嵌入式数据库
  • 内存小
  • 以本地文件的方式存储在磁盘上,只需要提供URL接口,不需要账号和密码
  • H2数据库可以随着程序一起发布,而MySQL是分布式发布

5.2 索引

  • 指定目录建立索引
  • 指定排除目录不建立索引(如windows系统下的目录)

5.3 检索

  • 根据用户指定信息进行模糊检索
  • 在检索过程可以过滤数据库找中本地不存在的文件

5.4 文件监听

  • Java程序运行在JVM虚拟机,无法对操作系统文件变化做出直接响应,有2种方式可以监听文件
  • 方法1:利用FileSystem提供文件系统的接口,WatchService接口监听文件系统变化,但是只能监听一级目录
  • 方法2:引入Apache Commons IO开源库,不停的遍历文件。由文件监控类FileAlterationMonitor中的线程不停的扫描文件观察器FileAlterationObserver,如果有文件的变化,则根据相关的文件比较器FileAlterationListener的实现类来判断文件时新增,还是删除,还是更改。
    FileAlterationListener专门用来接收文件系统的通知

5.4 命令行交互

  • 程序入口解析和配置:配置检索目录、排除目录、检索文件最大数量、排序策略

  • 交互式执行:帮助(help),索引(index),检索(search),退出(exit)

6.用法

6.1使用

java -jar  java_everything-1.0.0.jar args

args:

  • –maxReturn=20 :返回检索文件最大数量,输入将默认为30
  • –depthAsc=true/false:检索文件排序策略,默认为按照文件深度升序
  • –includePath=D: ,默认为C:, E:, D:, F:
  • –excludePath=E:a,C:Windows,默认为C:Windows, C:Program Files, C:Users, C:Program Files (x86)

6.2 命令
命令列表:
帮助:help
退出:exit
索引:index
检索:search fileName [fileType: img doc bin other]

6.3检索
不指定文件类型:

please input your require:
search java
D:java_ideal
C:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$II5NNUS.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RP8CE3K.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RMCQBYP.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RVOO91Q.java
D:VScodeworkWork2.java
D:VScodeworkR.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RNE5IIV.java
D:VScodeworkSort.java
D:VScodeworkRole.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RHY3Y3P.java
D:apache-maven-3.5.0libjavax.inject-1.jar
C:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RI5NNUS.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RBCNPQK.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RC0LCVR.java
C:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$IG2TV6R.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RDEUPYT.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RF1DSGG.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RT6JUJ6.java
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RUDQ80N.java

指定文件类型

please input your require:
search java doc
D:java_idealIntelliJ IDEA 2018.1.6licensejavaeeJar-CDDLv1.0.txt
C:UserslenovoDesktopjava.txt
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RMUW1XY.6licensejavaeeJar-CDDLv1.0.txt
C:Userslenovoeclipse-workspace.metadata.pluginsorg.eclipse.jdt.corejavaLikeNames.txt
C:UserslenovoDocumentsTencent Files2049161978FileRecvMobileFilejava3.txt
D:java_idealIntelliJ IDEA 2018.1.6pluginsKotlinkotlinclicensethird_partytestdatarxjava_license.txt
D:$RECYCLE.BINS-1-5-21-3937788977-1081121814-3639257697-1002$RMUW1XY.6pluginsKotlinkotlinclicensethird_part

7.收获

  • 学会用H2数据库来创建数据库,用数据源建立与数据库的连接
  • 锻炼了分析bug的能力以及编码能力
  • 熟悉Java的基本语法在实际项目中的应用,比如接口编程、线程池使用、单例模式、反射等
  • 用重构解决大量重复问题(insert/delete/select后需要关闭资源,将关闭资源单用一个方法)。

总结:
这是一个Java版的everything工具。可以解决Windows下的
搜索盘符限制,也就是可以搜索系统中所有文件。用户可以模糊搜索,
也可以指定文件类型进行搜索。采用的H2嵌入式数据库,
H2数据库以本地文件的方式存储在磁盘上,不需要账号和密码,而且内存小,
可以随着程序一起发布,而mysql是分布式发布。

该程序可以分为4个模块,分别是用户交互层、统一调度层、
业务层、持久化层(H2数据库)。

首先:用户交互层
当用户启用时,用户可以输入需要遍历的根目录和排除遍历的目录创建索引 。
也可以输入检索文件的最大数量以及按照文件深度排序策略。如果没有输入相关信息,将会按照默认值遍历C:,D:,E:,F:;
不遍历C:Windows, C:Program Files, C:Users, C:Program Files (x86);
按照检索文件默认最大数量为20,和按照深度升序排序来返回文件。

持久化层:
在数据库的表中存放是的文件信息表(文件名、文件路径、文件深度、文件类型)
当第一次使用或者重新建立索引时,需要初始化数据库建表操作。

业务层:

建立索引:将需要遍历的目录建立索引,比如根目录有C:, E:, D:, F:,
那么将会有4个线程分别遍历各自盘符将文件信息存储到数据库。

检索:用户输入查询信息在数据库检索 ,在检索过程中发现该文件再本地不存在,
会将该文件添加到阻塞队列,有一个后台清理线程池将该文件从数据库删除。

文件监听:当本地文件有新增、删除操作时,会通知数据库进行insert和delete。
Java程序运行在虚拟机,无法对操作系统文件变化做出直接响应。
监听文件有2种方法:
1.FileSystem提供的文件系统的接口。
FileSystem.getDefaut方法获得的默认文件系统提供对
Java虚拟机可访问的文件系统的访问,由此打通本地文件系统和Java虚拟机。
有一个接口WatchService可以监听文件系统的变化,
但是只能监听一级目录,无法监听更深层次的目录。

2.引入Apache Commons Io开源库。
库里有File monitor
在Apache的Commons-IO中有关于文件的监控功能的代码.
文件监控的原理如下:

  • 由文件监控类FileAlterationMonitor中的线程不停的扫描文件观察器FileAlterationObserver,
  • 如果有文件的变化,则根据相关的文件比较器FileAlterationListener的实现类来判断文件时新增,还是删除,还是更改。
  • FileAlterationListener专门用来接收文件系统的通知

调的bug:
1.连接数据库,启动的时候报错:testWhileIdle is true, validationQuery not set。
当数据库没有接受到连接请求时,会进行数据库连接检测,检出数据库是否还是连接着的,检查数据库 是否断开需要发送sql语句。报错是这个sql语句没有设置。
比如数据库连接池有10个,但是有2个人为终止,需要将这2个连接回收;
有100个连接,但是数据库性能只支持80个,查看是否所有连接可用。

如何解决:设置不进行空闲连接检测。
配置一个资源文件:
druild.properties文件:
validationQuery:SELECT 1
testWhileIdle:false
testOnBorrow:false
testOnReturn:false

读取资源文件:

 Properties p = new Properties();try {p.load(DataSourceFactory.class.getClassLoader().getResourceAsStream("druid.properties"));dataSource.setTestWhileIdle(Boolean.parseBoolean((String) p.get("testWhileIdle")));} catch (IOException e) {e.printStackTrace();}

2.数据库初始化

判断数据库是否需要初始化,用的是在当前目录下有没有mv.db文件,若没有就不会
数据库(也就没有表),但是这种方式是错误的,假如将该程序的jar包和依赖的第三方库lib发给其他
小伙伴进行检索,是会出问题的,因为只要数据库连接,就会由于mv.db文件,但是该数据库中并没有表,
所有初始化数据库需要在第一次使用或者重新建索引时。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平