目录

  • 一.项目背景
  • 二.项目使用技术栈与平台
  • 三.项目功能
  • 四.项目具体实现
    • 4.1:项目总体逻辑框架
    • 4.2:pom.xml文件导入依赖
    • 4.3:数据库表设计
    • 4.4:JDBC工具类设计
    • 4.5:JavaFX界面设计
    • 4.6:设计汉语拼音工具类
  • 五.效果展示

一.项目背景

  • 各个操作系统下,都有提供文件搜索的功能,如windows中查找文件:
    除系统自带的文件搜索功能外,也有大佬开发的很多搜索神器,比如Everything。
  • Everything是基于NTFS文件系统的USN Journal(Update SequenceNumber Journal),是利用操作系统记录的文件操作日志来进行搜索,特点是效率高,速度快,但是具有一定的局限性,只能用于NTFS文件系统。
  • 本项目使用实时的本地文件进行搜索,保存文件信息以便于提高搜索效率。

二.项目使用技术栈与平台

所用技术

  • JDBC(Java操作SQLite)
  • 数据库设计(数据库建库建表,增删查)
  • JavaFX(写一个图形化界面GUI)
  • pinyin4j(使用拼音与拼音首字母形式搜索文件)
  • 单例设计模式(饿汉模式创建数据库连接池的实例)

平台与环境

  • Windows
  • IDEA
  • Maven

三.项目功能

  • 通过UI界面选择一个要搜索的目录,显示该目录下的所有子文件的信息
  • 通过绑定UI界面的一个点击事件进行文件搜索操作,文件信息保存在数据库。如果已保存有的文件信息,执行本地目录与数据库文件信息比对操作,在更新到数据库。
  • 可以根据文件名,文件名的拼音以及拼音的首字母进行搜索,数据库操作是通过模糊匹配来进行操作,因此输入的文件名、拼音以及拼音首字母可以在文件全名的任何位置,换句话说,就是只要一个文件全名包含搜索框输入的内容,点击事件提交后,即可被显示出来

四.项目具体实现

4.1:项目总体逻辑框架

4.2:pom.xml文件导入依赖

<dependencies><dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.28.0</version></dependency><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>8</source><target>8</target><encoding>UTF-8</encoding></configuration></plugin></plugins></build>

知识扫盲:

1.JAVAFX是什么:

  • Java客户端UI库:JavaFX是一个强大的图形和多媒体处理工具包集合,它允许开发者来设计、创建、测试、调试和部署富客户端程序,并且和Java一样跨平台。
  • 提供了丰富的客户端组件:面板、按钮、文本框、表格等,还提供了各类事件、动画效果支持。
  • 提供了Web组件支持:HTML5的支持、CSS样式支持,JavaScript脚本支持。
  • 还提供了Scene Builder 程序,来支持拖拽式界面开发。
  • Java原有Swing、AWT客户端UI工具包,JavaFX 系统界面样式跟美观、系统架构对开发更友好、便捷

2.什么是SQLite数据库:

  • SQLite是一款轻量级的嵌入式内存数据库(嵌入在进程中,运行在内存中的数据库),使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
  • 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
  • 非常小,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
  • 无需安装、配置及管理。
  • 完全兼容事务的ACID四大特性,允许从多个进程或线程安全访问。
  • 支持多种开发语言,C, C++, PHP, Perl, Java, C#,Python, Ruby等
  • 支持 SQL92(SQL2)标准的大多数查询语言的功能。

3.Pinyin4j介绍:

  • 是一个Java的内库,提供对中文汉字到拼音的转换
  • 存在多音字的情况,根据一个字符可以获取多个字符串,其中字符串内容包括多音字的每个拼音以及声调,实在佩服开发出这些API的大牛们
输入:
String[] pinYins = PinyinHelper.toHanyuPinyinStringArray('乐');
System.out.println(Arrays.toString(pinYins));输出:
[le4, yue4]
  • 可以配置输出格式,包括大小写、是否带音调(默认带)、是否使用v(如绿的拼音lv)

4.3:数据库表设计

  • 需要保存的文件基本信息有:文件名称、路径、大小、上次修改时间
  • 文件名包含中文时,要满足全拼和拼音首字母的搜索,所以还需要保存全拼和拼音首字母中文汉字可能存在多音字的情况
  • 一般第一个拼音是最常用的,因此简单起见取第一个拼音即可

init.sql:

CREATE TABLE IF NOT EXISTS file_meta (id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(50) NOT NULL,path VARCHAR(1000) NOT NULL,is_directory BOOLEAN NOT NULL,pinyin VARCHAR(50) NOT NULL,pinyin_first VARCHAR(50) NOT NULL,size BIGINT NOT NULL,last_modified TIMESTAMP NOT NULL
);

4.4:JDBC工具类设计

  • URL格式为:jdbc:sqlite://数据库本地文件路径,没有用户名密码。使用URL创建DataSource对象后,会以该路径文件作为数据库,没有则创建该文件。
  • 设计单例模式获取DataSource连接池对象。及通过DataSource获取数据库连接的方法。
  • 提供获取数据库连接的方法
  • 初始化表:使用IO文件流进行sql文件读取,并执行。需要考虑多行sql代码的情况、sql注释的情况

//数据库连接类--使用单例--懒汉模式(双重校验锁)
public class DBUtil {private static volatile DataSource dataSource = null;private static Connection initConnection() {if (dataSource == null) {synchronized (DBUtil.class) {if (dataSource == null) {initDataSource();}}}//Connection对象是线程不安全的--每个线程必须拥有自己的Connection对象//一个线程只有一个Connection对象就不存在线程安全问题了//使用ThreadLocal实现,每个线程都有自己的Connection对象try {return dataSource.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}}//线程局部变量ThreadLocal,用于实现线程内的数据共享,即一个线程共享一份数据,另一个线程共享另外一份数据,互不干扰private static final ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<Connection>() {@Overrideprotected Connection initialValue() {return initConnection();}};public static Connection getConnection() {return connectionThreadLocal.get();}//jdbc操作连接数据库private static void initDataSource() {SQLiteDataSource sqLiteDataSource = new SQLiteDataSource();String url = "jdbc:sqlite://"+getDatabasePath();sqLiteDataSource.setUrl(url);dataSource = sqLiteDataSource;}//获取文件路径private static String getDatabasePath() {try{String classesPath = DBUtil.class.getProtectionDomain().getCodeSource().getLocation().getFile();File classDir = new File(URLDecoder.decode(classesPath,"UTF-8"));String path = classDir.getParent() + File.separator+"searcher.db";LogUtil.log("数据库文件路径为:%s",path);return path;} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}
}

4.5:JavaFX界面设计

  • 界面的搭建
<?xml version="1.0" encoding="UTF-8"?><?import javafx.geometry.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?><!--布局控件GridPane,fx:controller属性用于声明事件处理的Controller,值为Controller类的类全名-->
<!--xmlns用于声明默认命名空间,这里的声明随着你安装的Java JDK版本号的不同可以不同,但是最好不要比你安装的JDK版本高-->
<GridPane xmlns:fx="x"fx:id="rootPane"alignment="center"hgap="10" vgap="10"fx:controller="org.example.ui.Controller"><!--声明一个Button元素,fx:id用于给该Button一个标示,用于和Controller类中的Button实例进行绑定--><!--onMouseClicked用于绑定Button的点击事件,choose前面的#用于和Controller中处理函数进行绑定--><Button onMouseClicked="#choose" prefWidth="90" text="选择目录" GridPane.columnIndex="0" GridPane.rowIndex="0"/><Label fx:id="srcDirectory" text="请点击左边按钮"><GridPane.margin><Insets left="100.0"/></GridPane.margin></Label><TextField fx:id="searchField" prefWidth="900" GridPane.columnIndex="0" GridPane.rowIndex="1"/><TableView fx:id="fileTable"  prefHeight="700" prefWidth="900" GridPane.columnIndex="0" GridPane.columnSpan="2"GridPane.rowIndex="2"><columns><TableColumn fx:id="nameColumn" prefWidth="220" text="名称"><cellValueFactory><PropertyValueFactory property="name"/></cellValueFactory></TableColumn><TableColumn prefWidth="400" text="路径"><cellValueFactory><PropertyValueFactory property="path"/></cellValueFactory></TableColumn><TableColumn fx:id="sizeColumn" prefWidth="120" text="大小"><cellValueFactory><PropertyValueFactory property="lengthUI"/></cellValueFactory></TableColumn><TableColumn fx:id="lastModifiedColumn" prefWidth="160" text="修改时间"><cellValueFactory><PropertyValueFactory property="lastModifyUI"/></cellValueFactory></TableColumn></columns></TableView>
</GridPane>

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.example.service.DBService;import java.net.URL;public class MyApplication extends Application {@Overridepublic void start(Stage primaryStage) throws Exception {URL url = MyApplication.class.getClassLoader().getResource("app.fxml");if (url == null) {throw new RuntimeException("没有找到该文件");}Parent root = FXMLLoader.load(url);Scene scene = new Scene(root);primaryStage.setTitle("zdy-本地文件搜索引擎");primaryStage.setHeight(900);primaryStage.setWidth(1000);primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {DBService dbService = new DBService();//初始化,保证数据进来时,数据库就已经初始化好了dbService.init();//mian函数中必须调用launch方法,该方法会启动JavaFX程序。launch(args);}
}
  • 绑定选择文件目录事件,在每次事件发生时,调用该事件方法:启动目录扫描任务,并在完成后刷新表格
   //绑定鼠标点击事件@FXMLpublic void choose(MouseEvent mouseEvent) {DirectoryChooser chooser = new DirectoryChooser();//弹出对话框File rootFile = chooser.showDialog(rootPane.getScene().getWindow());if (rootFile == null) {return;}Thread thread = new Thread(()->//启动扫描任务fileScanner.scan(rootFile));thread.start();}
  • 绑定搜索框内容改变事件,在每次事件发生时,调用该事件方法:搜索文件信息,并刷新表格
    @Overridepublic void initialize(URL location, ResourceBundle resources) {//惠爱爱FXMLLoader.load执行时,实例化好AppController后调用StringProperty stringProperty = searchField.textProperty();//绑定一个搜索框输入时间,搜索框文本内容一旦更新,就会触发这个事件stringProperty.addListener(new ChangeListener<String>() {@Overridepublic void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {List<FileMeta> fileList = fileService.query(newValue.trim());//查询出来的数据显示在表中//涉及到UI的部分放在主线程中,因为会存在线程不安全问题Platform.runLater(()->{//先清空表中显示的前一次查询的数据fileTable.getItems().clear();//将新查询到的数据添加进去fileTable.getItems().addAll(fileList);});}});}

4.6:设计汉语拼音工具类

  • 使用第三方库提供的汉字到拼音的转换,一个汉字转换出来可能有多个拼音。
    配置汉字的字符范围,及拼音的输出格式(小写、不带音调)
  • API有提供单个字符的拼音转换:
String[] temp = PinyinHelper.toHanyuPinyinStringArray(c, PINYIN_OUTPUT_FORMAT);
  • 多个字符组成的文件名,需要按照每个字符返回的字符串数组进行排列组合,我们只简单实现,每个字符取第一个返回的字符串作为拼音。拼音分全拼,和汉字首字母拼接的两种方式

代码如下:


import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;import java.util.Arrays;//拼音类——将输入的汉字转换为拼音,从而支持拼音搜索功能
public class PinYinUtil {public static String getPinYinFirst(String name) {HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();format.setCaseType(HanyuPinyinCaseType.LOWERCASE);format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);StringBuilder sb = new StringBuilder();for (char ch : name.toLowerCase().toCharArray()) {try {String[] pinYinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format);if (pinYinArray == null || pinYinArray.length == 0) {sb.append(ch);continue;}//获取拼音的首字母sb.append(pinYinArray[0].charAt(0));} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {sb.append(ch);}}return sb.toString();}//根据输入的查询内容,如果是汉字,将汉字转换为拼音public static String getPinYin(String name) {HanyuPinyinOutputFormat hanyuPinyinOutputFormat = new HanyuPinyinOutputFormat();hanyuPinyinOutputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);hanyuPinyinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);StringBuilder sb = new StringBuilder();for (char ch: name.toLowerCase().toCharArray()) {try {String[] pinYinArray = PinyinHelper.toHanyuPinyinStringArray(ch,hanyuPinyinOutputFormat);if (pinYinArray == null || pinYinArray.length == 0) {sb.append(ch);continue;}//可能是多音字,若是多音字,只取拼音数组的第一个元素sb.append(pinYinArray[0]);} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {//说明输入的本来就是拼音,不需要转换为拼音sb.append(ch);}}return sb.toString();}
}

4.7:文件对比类

//处理数据库存在的文件和扫描到的文件的差集
public class DifferUtil {//找到文件1中有的而文件2中不存在的所有文件public static <E> List<E> differentSet(List<E> list1 , List<E> list2) {List<E> resultList = new ArrayList<>();for (E item : list1) {if (!list2.contains(item)) {//contains内部其实是调用的equals方法resultList.add(item);}}return resultList;}
}

五.效果展示

1.选择文件目录,扫描本地文件,保存文件信息并显示

2.根据文件名搜索

3.根据拼音搜索

4.根据拼音首字母搜素

本地文件搜索引擎项目说明相关推荐

  1. go实现本地文件搜索引擎

    // filelist.go package mainimport (//"flag""fmt""os""path/filepat ...

  2. 项目实战——基于Java8+JavaFX+多线程+文件IO+SQLite数据库实现的本地文件快速搜索引擎详细设计实现

    目录 一.前言介绍 二.功能展示 2.1选择所要查找的文件夹 2.2将所选目录下的所有文件进行属性展示 2.3支持搜索框查询文件(模糊查询) 2.4统计本次扫描信息 ​编辑 三.整体设计 3.1工具类 ...

  3. java文件搜索引擎在网页上打开本地文件链接的解决办法

    首先需要强调的是,a标签无法打开本地文件链接(具体为无反应,无跳转). 于是换个思路:由于java程序可以打开本地文件,于是我们可以从网页获取本地文件链接,并将其传到java程序中,然后通过该程序打开 ...

  4. windows系统搜索本地文件缓慢怎么办?

    伴随着时代发展,互联网也慢慢走进了千家万户,越来越多的人也开始使用了解互联网,而对互联网个人角度起到支撑作用的个人用户机,也就是个人电脑(Personal computer,简称PC)的安装量和使用量 ...

  5. AnyTXT 一款强大的本地文件内容搜索软件

    一款强大的本地文件内容搜索软件,可搜索文件中的文字 Windows作为市场占有率最高的PC操作系统,它有着难以计数的桌面应用,搜索类工具自然不在话下, ·Everything ·Listary ·Wo ...

  6. 如虎添翼!一款强大的本地文件全文搜索工具

    ↑↑↑关注后"星标"简说Python 人人都可以简单入门Python.爬虫.数据分析 简说Python推荐来源:平凡而诗意 作者:JackpopOne old watch, lik ...

  7. HTML5 本地文件操作之FileSystemAPI整理(二)

    一.文件目录操作 1.DirectoryEntry对象 属性: 1.isFile: 操作对象的是否为文件,DirectoryEntry对象固定其值为false 2.isDirectory: 操作对象是 ...

  8. gbase 导出_GBase 8a导出本地文件时多了目录,gbase_export_directory参数用处

    GBase 8a数据库集群提供select into outfile方式导出数据到文件,指定本地文件时,数据库参数gbase_export_directory会自动创建同名的目录.如果想去掉,需要关闭 ...

  9. 浅谈本地文件包含利用

    今天在公众号看到了一个本地文件包含的利用工具,看了下国外大牛对该工具的使用的一个视频,感觉很厉害,通过该工具可对存在本地文件包含漏洞的站点进行利用并返回一个LFI shell,通过返回的LFI she ...

最新文章

  1. 《java编程思想》学习笔记——内部类五
  2. 安卓mysql插入数据_【11-25求助】关于Android 的SQLite数据库插入数据报错问题
  3. 少年派的一生,树莓派的十年,Raspberry Pi上市十周年
  4. Microsoft Bot Builder Overview
  5. webview 模拟点击_Android如何基于坐标对View进行模拟点击事件详解
  6. 多人在线答题游戏 小程序 (规划设计方案)
  7. PHP利用GD库将微信小程序二维码和用户头像拼接且用户在微信服务号回复指定内容将拼接的二维码返回
  8. 千脑跳转页面下的安全分析
  9. Java中的IO流基础(1)
  10. 台式计算机连接投影仪无信号,投影仪连接电脑没反应 电脑连接投影仪无信号解决办法...
  11. 【朋友刀刀画展一游】谢谢刀刀!
  12. [人工智能-深度学习-32]:卷积神经网络CNN - 常见分类网络- AlexNet网络结构分析与详解
  13. inv在线计算机,INV3062A
  14. 动网产品失败, 合作伙伴寒心离去
  15. vue 子组件与父组件运行的顺序
  16. PAT_乙级_1006_筱筱
  17. SpringBoot2整合ElasticSearch(包含ElasticSearch入门+spring-boot-starter-data-elasticsearch)
  18. oracle12c创建表空间、创建用户、创建权限
  19. ceph-deploy osd activate xxx bluestore ERROR
  20. jQuery与Ajax 面试题库(长期更新中...)

热门文章

  1. 【?】【9908】守望者的逃离
  2. 8寸7寸触摸屏常见的故障问题和维修方法分别是什么?
  3. echarts图表折线图柱状图多个X轴Y轴以及一个Y轴反向
  4. 万户OA助力红豆集团信息化建设方案
  5. The Things Network LoRaWAN Stack V3 学习笔记 2.5 LoRa节点配置接入
  6. 计算机应用技术机测,[计算机应用技术]阶段测评1(2016年版)(13页)-原创力文档...
  7. PTA甲级模拟第九弹:1114-1117
  8. 第三--JVM与线程
  9. 0pyqt获取textEdit控件的文本
  10. 腾讯云数据库 TencentDB for MariaDB快速入门和常见问题