Skip to content

Commit 7837a44

Browse files
committed
优化文件搜索工具。
1 parent 0764204 commit 7837a44

4 files changed

Lines changed: 84 additions & 71 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@
251251
<dependency>
252252
<groupId>org.apache.lucene</groupId>
253253
<artifactId>lucene-core</artifactId>
254-
<version>7.1.0</version>
254+
<version>8.2.0</version>
255255
</dependency>
256256

257257
</dependencies>

src/main/java/com/xwintop/xJavaFxTool/controller/littleTools/FileSearchToolController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,17 @@ private void initEvent() {
5555
private void initService() {
5656
}
5757

58-
public void searchContentAction() throws Exception{
58+
public void searchContentAction() throws Exception {
5959
fileSearchToolService.searchContentAction();
6060
}
6161

6262
@FXML
63-
private void refreshIndexAction(ActionEvent event) throws Exception{
63+
private void refreshIndexAction(ActionEvent event) throws Exception {
6464
fileSearchToolService.refreshIndexAction();
6565
}
6666

6767
@FXML
68-
private void searchDirectoryAction(ActionEvent event) throws Exception{
68+
private void searchDirectoryAction(ActionEvent event) throws Exception {
6969
File file = FileChooserUtil.chooseDirectory();
7070
if (file != null) {
7171
searchDirectoryTextField.setText(file.getPath());

src/main/java/com/xwintop/xJavaFxTool/services/littleTools/FileSearchToolService.java

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import cn.hutool.core.thread.ThreadUtil;
44
import com.xwintop.xJavaFxTool.controller.littleTools.FileSearchToolController;
55
import com.xwintop.xJavaFxTool.utils.ConfigureUtil;
6+
import com.xwintop.xcore.util.javafx.TooltipUtil;
67
import lombok.Getter;
78
import lombok.Setter;
89
import lombok.extern.slf4j.Slf4j;
910
import org.apache.commons.io.FileUtils;
1011
import org.apache.commons.lang3.StringUtils;
1112
import org.apache.lucene.analysis.Analyzer;
1213
import org.apache.lucene.analysis.standard.StandardAnalyzer;
13-
import org.apache.lucene.document.DateTools;
1414
import org.apache.lucene.document.Document;
1515
import org.apache.lucene.document.Field;
1616
import org.apache.lucene.document.StringField;
@@ -25,6 +25,7 @@
2525
import java.nio.file.Files;
2626
import java.nio.file.Path;
2727
import java.nio.file.Paths;
28+
import java.util.Date;
2829
import java.util.HashMap;
2930
import java.util.Iterator;
3031
import java.util.Map;
@@ -45,18 +46,14 @@ public class FileSearchToolService {
4546
private static final String searchIndexDir = ConfigureUtil.getConfigurePath("searchIndexDir/");
4647

4748
private static IndexWriter indexWriter = null;
48-
// private static IndexSearcher indexSearcher = null;
49+
50+
// private static RAMDirectory directory;
4951

5052
static {
5153
File searchIndexDirFile = new File(searchIndexDir);
5254
try {
5355
FileUtils.forceMkdir(searchIndexDirFile);
5456
Directory directory = FSDirectory.open(searchIndexDirFile.toPath());
55-
// Analyzer analyzer = new StandardAnalyzer(); // 标准分词器,适用于英文
56-
// //创建索引写入配置
57-
// IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
58-
// //创建索引写入对象
59-
// indexWriter = new IndexWriter(directory, indexWriterConfig);
6057
getIndexWriter(directory);
6158
if (!DirectoryReader.indexExists(directory)) {
6259
indexWriter.close();
@@ -71,13 +68,14 @@ public static void getIndexWriter(Directory directory) throws IOException {
7168
Analyzer analyzer = new StandardAnalyzer(); // 标准分词器,适用于英文
7269
//创建索引写入配置
7370
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
71+
indexWriterConfig.setRAMBufferSizeMB(Runtime.getRuntime().totalMemory() / 1024 / 1024 / 4);
72+
// indexWriterConfig.setMaxBufferedDocs(2000);
7473
//创建索引写入对象
7574
indexWriter = new IndexWriter(directory, indexWriterConfig);
7675
}
7776

7877
public IndexSearcher getIndexSearcher() {
7978
IndexSearcher indexSearcher = null;
80-
// if (indexSearcher == null) {
8179
try {
8280
Directory directory = FSDirectory.open(Paths.get(searchIndexDir));
8381
// 创建索引的读取器
@@ -87,7 +85,6 @@ public IndexSearcher getIndexSearcher() {
8785
} catch (Exception e) {
8886
log.error("创建索引读取器失败:", e);
8987
}
90-
// }
9188
return indexSearcher;
9289
}
9390

@@ -100,7 +97,7 @@ public void searchContentAction() throws Exception {
10097
String path = fileSearchToolController.getSearchDirectoryTextField().getText().trim();
10198
BooleanQuery.Builder builder = new BooleanQuery.Builder();
10299
String fileName = "fileName";
103-
if (fileSearchToolController.getMatchCaseCheckBox().isSelected()) {
100+
if (!fileSearchToolController.getMatchCaseCheckBox().isSelected()) {
104101
fileName = "fileNameLowerCase";
105102
queryText = queryText.toLowerCase();
106103
}
@@ -136,39 +133,50 @@ public void searchContentAction() throws Exception {
136133
}
137134
BooleanQuery query = builder.build();
138135
IndexSearcher indexSearcher = getIndexSearcher();
139-
TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE);
136+
TopDocs topDocs = indexSearcher.search(query, 100);
140137
fileSearchToolController.getSearchResultTableData().clear();
141138
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
142139
//取得对应的文档对象
143140
Document document = indexSearcher.doc(scoreDoc.doc);
144141
// System.out.println("fileName:" + document.get("fileName"));
145-
// System.out.println("absolutePath:" + document.get("absolutePath"));
146142
Map map = new HashMap();
147143
map.put("fileName", document.get("fileName"));
148144
map.put("absolutePath", document.get("absolutePath"));
149145
map.put("fileSize", document.get("fileSize"));
150-
map.put("lastModified", document.get("lastModified"));
146+
// map.put("lastModified", document.get("lastModified"));
147+
map.put("lastModified", new Date(Long.parseLong(document.get("lastModified"))).toLocaleString());
151148
fileSearchToolController.getSearchResultTableData().add(map);
152149
}
153-
fileSearchToolController.getSearchTextLabel().setText("总共查询到" + topDocs.totalHits + "个文档");
150+
int allCount = indexSearcher.count(new MatchAllDocsQuery());
151+
fileSearchToolController.getSearchTextLabel().setText("总共查询到" + topDocs.totalHits.value + "个文档;当前一共缓存" + allCount + "个文档");
154152
}
155153

156154
public void refreshIndexAction() throws Exception {
157155
String path = fileSearchToolController.getSearchDirectoryTextField().getText();
158-
addSearchIndexFile(path);
156+
if (StringUtils.isEmpty(path)) {
157+
TooltipUtil.showToast("路径不能为空!");
158+
return;
159+
}
160+
addSearchIndexFile(Paths.get(path));
159161
}
160162

161-
public void addSearchIndexFile(String path) {
163+
public void addSearchIndexFile(Path path) {
162164
ThreadUtil.execute(() -> {
163165
try {
164-
DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(path));
166+
DirectoryStream<Path> stream = Files.newDirectoryStream(path);
165167
Iterator<Path> pathIterator = stream.iterator();
166168
while (pathIterator.hasNext()) {
167169
Path curPath = pathIterator.next();
168-
addIndexDocument(curPath.toFile());
169-
if (Files.isDirectory(curPath)) {
170-
addSearchIndexFile(curPath.toString());
171-
}
170+
ThreadUtil.execute(() -> {
171+
try {
172+
addIndexDocument(curPath.toFile());
173+
if (Files.isDirectory(curPath)) {
174+
addSearchIndexFile(curPath);
175+
}
176+
} catch (Exception e) {
177+
log.warn("添加索引失败:", e);
178+
}
179+
});
172180
}
173181
} catch (Exception e) {
174182
log.warn("获取失败:", e);
@@ -179,16 +187,24 @@ public void addSearchIndexFile(String path) {
179187
public void addIndexDocument(File file) throws Exception {
180188
Document doc = new Document();
181189
doc.add(new StringField("fileName", file.getName(), Field.Store.YES));
182-
doc.add(new StringField("fileNameLowerCase", file.getName().toLowerCase(), Field.Store.YES));
190+
doc.add(new StringField("fileNameLowerCase", file.getName().toLowerCase(), Field.Store.NO));
183191
doc.add(new StringField("absolutePath", file.getAbsolutePath(), Field.Store.YES));
184192
// doc.add(new DoubleDocValuesField("fileSize", file.length()));
185193
// doc.add(new DoubleDocValuesField("lastModified", file.lastModified()));
186194
doc.add(new StringField("fileSize", String.valueOf(file.length()), Field.Store.YES));
187-
doc.add(new StringField("lastModified", DateTools.timeToString(file.lastModified(), DateTools.Resolution.MILLISECOND), Field.Store.YES));
188-
doc.add(new StringField("isHidden", String.valueOf(file.isHidden()), Field.Store.YES));
189-
doc.add(new StringField("isDirectory", String.valueOf(file.isDirectory()), Field.Store.YES));
195+
doc.add(new StringField("lastModified", String.valueOf(file.lastModified()), Field.Store.YES));
196+
doc.add(new StringField("isHidden", String.valueOf(file.isHidden()), Field.Store.NO));
197+
doc.add(new StringField("isDirectory", String.valueOf(file.isDirectory()), Field.Store.NO));
190198
indexWriter.updateDocument(new Term("absolutePath", file.getAbsolutePath()), doc);
191199
// indexWriter.addDocument(doc);
192200
indexWriter.commit();
193201
}
202+
203+
public void autoRefreshIndexAction() {
204+
File[] listRoots = File.listRoots();
205+
for (File listRoot : listRoots) {
206+
System.out.println("加载目录: " + listRoot.getAbsolutePath());
207+
addSearchIndexFile(listRoot.toPath());
208+
}
209+
}
194210
}

src/main/resources/com/xwintop/xJavaFxTool/fxmlView/littleTools/FileSearchTool.fxml

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,58 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

3+
<?import java.lang.String?>
34
<?import javafx.collections.FXCollections?>
45
<?import javafx.geometry.Insets?>
5-
<?import javafx.scene.control.*?>
6-
<?import javafx.scene.layout.*?>
7-
<?import java.lang.*?>
8-
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171"
9-
xmlns:fx="http://javafx.com/fxml/1"
10-
fx:controller="com.xwintop.xJavaFxTool.controller.littleTools.FileSearchToolController">
6+
<?import javafx.scene.control.Button?>
7+
<?import javafx.scene.control.CheckBox?>
8+
<?import javafx.scene.control.ChoiceBox?>
9+
<?import javafx.scene.control.Label?>
10+
<?import javafx.scene.control.TableColumn?>
11+
<?import javafx.scene.control.TableView?>
12+
<?import javafx.scene.control.TextField?>
13+
<?import javafx.scene.layout.AnchorPane?>
14+
<?import javafx.scene.layout.BorderPane?>
15+
<?import javafx.scene.layout.HBox?>
16+
<?import javafx.scene.layout.VBox?>
17+
18+
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.xwintop.xJavaFxTool.controller.littleTools.FileSearchToolController">
1119
<children>
12-
<BorderPane AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
13-
AnchorPane.topAnchor="10.0">
20+
<BorderPane AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
1421
<top>
1522
<VBox spacing="5.0" BorderPane.alignment="CENTER">
1623
<children>
1724
<HBox alignment="CENTER_LEFT" spacing="5.0">
1825
<children>
19-
<TextField fx:id="searchContentTextField" onKeyReleased="#searchContentAction"
20-
promptText="请输入搜索内容" HBox.hgrow="ALWAYS"/>
21-
<CheckBox fx:id="autoRefreshIndexCheckBox" mnemonicParsing="false" selected="true"
22-
text="自动刷新索引"/>
23-
<Button fx:id="refreshIndexButton" mnemonicParsing="false"
24-
onAction="#refreshIndexAction" text="刷新索引"/>
26+
<TextField fx:id="searchContentTextField" onKeyReleased="#searchContentAction" promptText="请输入搜索内容" HBox.hgrow="ALWAYS" />
27+
<CheckBox fx:id="autoRefreshIndexCheckBox" mnemonicParsing="false" selected="true" text="自动刷新索引" />
28+
<Button fx:id="refreshIndexButton" mnemonicParsing="false" onAction="#refreshIndexAction" text="刷新索引" />
2529
</children>
2630
</HBox>
2731
<HBox alignment="CENTER_LEFT" spacing="5.0">
2832
<children>
29-
<CheckBox fx:id="regularCheckBox" mnemonicParsing="false"
30-
onAction="#searchContentAction" text="正则表达式"/>
31-
<CheckBox fx:id="matchCaseCheckBox" mnemonicParsing="false"
32-
onAction="#searchContentAction" text="区分大小写"/>
33-
<CheckBox fx:id="fullTextMatchingCheckBox" mnemonicParsing="false"
34-
onAction="#searchContentAction" text="全字匹配"/>
35-
<ChoiceBox fx:id="showHideFileChoice" value="所有" onAction="#searchContentAction">
33+
<CheckBox fx:id="regularCheckBox" mnemonicParsing="false" onAction="#searchContentAction" text="正则表达式" />
34+
<CheckBox fx:id="matchCaseCheckBox" mnemonicParsing="false" onAction="#searchContentAction" text="区分大小写" />
35+
<CheckBox fx:id="fullTextMatchingCheckBox" mnemonicParsing="false" onAction="#searchContentAction" text="全字匹配" />
36+
<ChoiceBox fx:id="showHideFileChoice" onAction="#searchContentAction" value="所有">
3637
<items>
3738
<FXCollections fx:factory="observableArrayList">
38-
<String fx:value="所有"/>
39-
<String fx:value="非隐藏"/>
40-
<String fx:value="隐藏文件"/>
39+
<String fx:value="所有" />
40+
<String fx:value="非隐藏" />
41+
<String fx:value="隐藏文件" />
4142
</FXCollections>
4243
</items>
4344
</ChoiceBox>
44-
<ChoiceBox fx:id="fileTypeChoiceBox" value="所有" onAction="#searchContentAction">
45+
<ChoiceBox fx:id="fileTypeChoiceBox" onAction="#searchContentAction" value="所有">
4546
<items>
4647
<FXCollections fx:factory="observableArrayList">
47-
<String fx:value="所有"/>
48-
<String fx:value="文件"/>
49-
<String fx:value="文件夹"/>
48+
<String fx:value="所有" />
49+
<String fx:value="文件" />
50+
<String fx:value="文件夹" />
5051
</FXCollections>
5152
</items>
5253
</ChoiceBox>
53-
<TextField fx:id="searchDirectoryTextField" onKeyReleased="#searchContentAction"
54-
promptText="搜索文件夹" HBox.hgrow="ALWAYS"/>
55-
<Button fx:id="searchDirectoryButton" mnemonicParsing="false"
56-
onAction="#searchDirectoryAction" text="浏览"/>
54+
<TextField fx:id="searchDirectoryTextField" onKeyReleased="#searchContentAction" promptText="搜索文件夹" HBox.hgrow="ALWAYS" />
55+
<Button fx:id="searchDirectoryButton" mnemonicParsing="false" onAction="#searchDirectoryAction" text="浏览" />
5756
</children>
5857
</HBox>
5958
</children>
@@ -62,28 +61,26 @@
6261
<center>
6362
<TableView fx:id="searchResultTableVIew" BorderPane.alignment="CENTER">
6463
<columns>
65-
<TableColumn fx:id="fileNameTableColumn" minWidth="60.0" prefWidth="120.0" text="名称"/>
66-
<TableColumn fx:id="absolutePathTableColumn" minWidth="120.0" prefWidth="240.0" text="路径"/>
67-
<TableColumn fx:id="fileSizeTableColumn" maxWidth="120.0" minWidth="40.0" prefWidth="60.0"
68-
text="大小"/>
69-
<TableColumn fx:id="lastModifiedTableColumn" maxWidth="200.0" minWidth="60.0" prefWidth="120.0"
70-
text="修改时间"/>
64+
<TableColumn fx:id="fileNameTableColumn" minWidth="100.0" prefWidth="200.0" text="名称" />
65+
<TableColumn fx:id="absolutePathTableColumn" minWidth="200.0" prefWidth="400.0" text="路径" />
66+
<TableColumn fx:id="fileSizeTableColumn" maxWidth="160.0" minWidth="60.0" prefWidth="100.0" text="大小" />
67+
<TableColumn fx:id="lastModifiedTableColumn" maxWidth="200.0" minWidth="120.0" prefWidth="160.0" text="修改时间" />
7168
</columns>
7269
<BorderPane.margin>
73-
<Insets top="10.0"/>
70+
<Insets top="10.0" />
7471
</BorderPane.margin>
7572
<columnResizePolicy>
76-
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
73+
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
7774
</columnResizePolicy>
7875
</TableView>
7976
</center>
8077
<bottom>
8178
<HBox alignment="CENTER_LEFT" BorderPane.alignment="CENTER">
8279
<children>
83-
<Label fx:id="searchTextLabel" text="正在搜索中..."/>
80+
<Label fx:id="searchTextLabel" text="正在搜索中..." />
8481
</children>
8582
<BorderPane.margin>
86-
<Insets top="5.0"/>
83+
<Insets top="5.0" />
8784
</BorderPane.margin>
8885
</HBox>
8986
</bottom>

0 commit comments

Comments
 (0)