Skip to content

Commit 0764204

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

3 files changed

Lines changed: 180 additions & 81 deletions

File tree

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

Lines changed: 87 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import lombok.Setter;
88
import lombok.extern.slf4j.Slf4j;
99
import org.apache.commons.io.FileUtils;
10+
import org.apache.commons.lang3.StringUtils;
1011
import org.apache.lucene.analysis.Analyzer;
1112
import org.apache.lucene.analysis.standard.StandardAnalyzer;
1213
import org.apache.lucene.document.DateTools;
1314
import org.apache.lucene.document.Document;
1415
import org.apache.lucene.document.Field;
15-
import org.apache.lucene.document.TextField;
16+
import org.apache.lucene.document.StringField;
1617
import org.apache.lucene.index.*;
1718
import org.apache.lucene.search.*;
1819
import org.apache.lucene.store.Directory;
@@ -44,54 +45,112 @@ public class FileSearchToolService {
4445
private static final String searchIndexDir = ConfigureUtil.getConfigurePath("searchIndexDir/");
4546

4647
private static IndexWriter indexWriter = null;
47-
private static IndexSearcher indexSearcher = null;
48+
// private static IndexSearcher indexSearcher = null;
4849

4950
static {
5051
File searchIndexDirFile = new File(searchIndexDir);
5152
try {
5253
FileUtils.forceMkdir(searchIndexDirFile);
5354
Directory directory = FSDirectory.open(searchIndexDirFile.toPath());
54-
Analyzer analyzer = new StandardAnalyzer(); // 标准分词器,适用于英文
55-
//创建索引写入配置
56-
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
57-
//创建索引写入对象
58-
indexWriter = new IndexWriter(directory, indexWriterConfig);
55+
// Analyzer analyzer = new StandardAnalyzer(); // 标准分词器,适用于英文
56+
// //创建索引写入配置
57+
// IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
58+
// //创建索引写入对象
59+
// indexWriter = new IndexWriter(directory, indexWriterConfig);
60+
getIndexWriter(directory);
61+
if (!DirectoryReader.indexExists(directory)) {
62+
indexWriter.close();
63+
getIndexWriter(directory);
64+
}
65+
} catch (Exception e) {
66+
log.error("创建文件失败!", e);
67+
}
68+
}
5969

70+
public static void getIndexWriter(Directory directory) throws IOException {
71+
Analyzer analyzer = new StandardAnalyzer(); // 标准分词器,适用于英文
72+
//创建索引写入配置
73+
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
74+
//创建索引写入对象
75+
indexWriter = new IndexWriter(directory, indexWriterConfig);
76+
}
77+
78+
public IndexSearcher getIndexSearcher() {
79+
IndexSearcher indexSearcher = null;
80+
// if (indexSearcher == null) {
81+
try {
82+
Directory directory = FSDirectory.open(Paths.get(searchIndexDir));
6083
// 创建索引的读取器
6184
IndexReader indexReader = DirectoryReader.open(directory);
6285
// 创建一个索引的查找器,来检索索引库
6386
indexSearcher = new IndexSearcher(indexReader);
64-
} catch (IOException e) {
65-
log.error("创建文件失败!", e);
87+
} catch (Exception e) {
88+
log.error("创建索引读取器失败:", e);
6689
}
90+
// }
91+
return indexSearcher;
6792
}
6893

6994
public FileSearchToolService(FileSearchToolController fileSearchToolController) {
7095
this.fileSearchToolController = fileSearchToolController;
7196
}
7297

7398
public void searchContentAction() throws Exception {
74-
String queryText = fileSearchToolController.getSearchContentTextField().getText();
75-
if (!fileSearchToolController.getFullTextMatchingCheckBox().isSelected()) {
76-
queryText = "*" + queryText + "*";
99+
String queryText = fileSearchToolController.getSearchContentTextField().getText().trim();
100+
String path = fileSearchToolController.getSearchDirectoryTextField().getText().trim();
101+
BooleanQuery.Builder builder = new BooleanQuery.Builder();
102+
String fileName = "fileName";
103+
if (fileSearchToolController.getMatchCaseCheckBox().isSelected()) {
104+
fileName = "fileNameLowerCase";
105+
queryText = queryText.toLowerCase();
106+
}
107+
if (fileSearchToolController.getRegularCheckBox().isSelected()) {
108+
Query fileNameQuery = new RegexpQuery(new Term(fileName, queryText));//正则搜索
109+
builder.add(fileNameQuery, BooleanClause.Occur.MUST);
110+
} else {
111+
if (fileSearchToolController.getFullTextMatchingCheckBox().isSelected()) {
112+
Query fileNameQuery = new TermQuery(new Term(fileName, queryText));
113+
builder.add(fileNameQuery, BooleanClause.Occur.MUST);
114+
} else {
115+
Query fileNameQuery = new WildcardQuery(new Term(fileName, "*" + queryText + "*"));// 通配符
116+
builder.add(fileNameQuery, BooleanClause.Occur.MUST);
117+
}
118+
}
119+
if (fileSearchToolController.getShowHideFileChoice().getSelectionModel().getSelectedIndex() == 1) {
120+
TermQuery isHiddenQuery = new TermQuery(new Term("isHidden", "false"));
121+
builder.add(isHiddenQuery, BooleanClause.Occur.MUST);
122+
} else if (fileSearchToolController.getShowHideFileChoice().getSelectionModel().getSelectedIndex() == 2) {
123+
TermQuery isHiddenQuery = new TermQuery(new Term("isHidden", "true"));
124+
builder.add(isHiddenQuery, BooleanClause.Occur.MUST);
125+
}
126+
if (fileSearchToolController.getFileTypeChoiceBox().getSelectionModel().getSelectedIndex() == 1) {
127+
TermQuery isDirectoryQuery = new TermQuery(new Term("isDirectory", "false"));
128+
builder.add(isDirectoryQuery, BooleanClause.Occur.MUST);
129+
} else if (fileSearchToolController.getFileTypeChoiceBox().getSelectionModel().getSelectedIndex() == 2) {
130+
TermQuery isDirectoryQuery = new TermQuery(new Term("isDirectory", "true"));
131+
builder.add(isDirectoryQuery, BooleanClause.Occur.MUST);
132+
}
133+
if (StringUtils.isNotEmpty(path)) {
134+
PrefixQuery pathQuery = new PrefixQuery(new Term("absolutePath", path));// 字段搜索 Field:Keyword,自动在结尾添加 *
135+
builder.add(pathQuery, BooleanClause.Occur.MUST);
77136
}
78-
Query query = new WildcardQuery(new Term("fileName", queryText));
79-
TopDocs topDocs = indexSearcher.search(query, 100);
80-
//打印查询到的记录数
81-
// System.out.println("总共查询到" + topDocs.totalHits + "个文档");
137+
BooleanQuery query = builder.build();
138+
IndexSearcher indexSearcher = getIndexSearcher();
139+
TopDocs topDocs = indexSearcher.search(query, Integer.MAX_VALUE);
82140
fileSearchToolController.getSearchResultTableData().clear();
83141
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
84142
//取得对应的文档对象
85143
Document document = indexSearcher.doc(scoreDoc.doc);
86144
// System.out.println("fileName:" + document.get("fileName"));
87-
System.out.println("absolutePath:" + document.get("absolutePath"));
145+
// System.out.println("absolutePath:" + document.get("absolutePath"));
88146
Map map = new HashMap();
89147
map.put("fileName", document.get("fileName"));
90148
map.put("absolutePath", document.get("absolutePath"));
91149
map.put("fileSize", document.get("fileSize"));
92150
map.put("lastModified", document.get("lastModified"));
93151
fileSearchToolController.getSearchResultTableData().add(map);
94152
}
153+
fileSearchToolController.getSearchTextLabel().setText("总共查询到" + topDocs.totalHits + "个文档");
95154
}
96155

97156
public void refreshIndexAction() throws Exception {
@@ -106,26 +165,28 @@ public void addSearchIndexFile(String path) {
106165
Iterator<Path> pathIterator = stream.iterator();
107166
while (pathIterator.hasNext()) {
108167
Path curPath = pathIterator.next();
168+
addIndexDocument(curPath.toFile());
109169
if (Files.isDirectory(curPath)) {
110170
addSearchIndexFile(curPath.toString());
111-
} else {
112-
// System.out.println(curPath.toString());
113-
addIndexDocument(curPath.toFile());
114171
}
115172
}
116173
} catch (Exception e) {
117-
log.error("获取失败:", e);
174+
log.warn("获取失败:", e);
118175
}
119176
});
120177
}
121178

122179
public void addIndexDocument(File file) throws Exception {
123180
Document doc = new Document();
124-
doc.add(new TextField("fileName", file.getName(), Field.Store.YES));
125-
doc.add(new TextField("absolutePath", file.getAbsolutePath(), Field.Store.YES));
126-
// doc.add(new LongPoint("fileSize", file.length()));
127-
doc.add(new TextField("fileSize", String.valueOf(file.length()), Field.Store.YES));
128-
doc.add(new TextField("lastModified", DateTools.timeToString(file.lastModified(), DateTools.Resolution.MILLISECOND), Field.Store.YES));
181+
doc.add(new StringField("fileName", file.getName(), Field.Store.YES));
182+
doc.add(new StringField("fileNameLowerCase", file.getName().toLowerCase(), Field.Store.YES));
183+
doc.add(new StringField("absolutePath", file.getAbsolutePath(), Field.Store.YES));
184+
// doc.add(new DoubleDocValuesField("fileSize", file.length()));
185+
// doc.add(new DoubleDocValuesField("lastModified", file.lastModified()));
186+
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));
129190
indexWriter.updateDocument(new Term("absolutePath", file.getAbsolutePath()), doc);
130191
// indexWriter.addDocument(doc);
131192
indexWriter.commit();

src/main/java/com/xwintop/xJavaFxTool/view/littleTools/FileSearchToolView.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ public abstract class FileSearchToolView implements Initializable {
3131
@FXML
3232
protected CheckBox fullTextMatchingCheckBox;
3333
@FXML
34-
protected CheckBox showHideFileCheckBox;
34+
protected ChoiceBox showHideFileChoice;
35+
@FXML
36+
protected ChoiceBox fileTypeChoiceBox;
3537
@FXML
3638
protected TextField searchDirectoryTextField;
3739
@FXML
@@ -46,5 +48,7 @@ public abstract class FileSearchToolView implements Initializable {
4648
protected TableColumn<Map<String, String>, String> fileSizeTableColumn;
4749
@FXML
4850
protected TableColumn<Map<String, String>, String> lastModifiedTableColumn;
51+
@FXML
52+
protected Label searchTextLabel;
4953

5054
}
Lines changed: 88 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,92 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22

3+
<?import javafx.collections.FXCollections?>
34
<?import javafx.geometry.Insets?>
4-
<?import javafx.scene.control.Button?>
5-
<?import javafx.scene.control.CheckBox?>
6-
<?import javafx.scene.control.TableColumn?>
7-
<?import javafx.scene.control.TableView?>
8-
<?import javafx.scene.control.TextField?>
9-
<?import javafx.scene.layout.AnchorPane?>
10-
<?import javafx.scene.layout.BorderPane?>
11-
<?import javafx.scene.layout.HBox?>
12-
<?import javafx.scene.layout.VBox?>
13-
14-
<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">
15-
<children>
16-
<BorderPane AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
17-
<top>
18-
<VBox spacing="5.0" BorderPane.alignment="CENTER">
19-
<children>
20-
<HBox alignment="CENTER_LEFT" spacing="5.0">
21-
<children>
22-
<TextField fx:id="searchContentTextField" promptText="请输入搜索内容" onKeyReleased="#searchContentAction" HBox.hgrow="ALWAYS" />
23-
<CheckBox fx:id="autoRefreshIndexCheckBox" mnemonicParsing="false" selected="true" text="自动刷新索引" />
24-
<Button fx:id="refreshIndexButton" mnemonicParsing="false" onAction="#refreshIndexAction" text="刷新索引" />
25-
</children>
26-
</HBox>
27-
<HBox alignment="CENTER_LEFT" spacing="5.0">
28-
<children>
29-
<CheckBox fx:id="regularCheckBox" mnemonicParsing="false" text="正则表达式" />
30-
<CheckBox fx:id="matchCaseCheckBox" mnemonicParsing="false" text="区分大小写" />
31-
<CheckBox fx:id="fullTextMatchingCheckBox" mnemonicParsing="false" text="全字匹配" />
32-
<CheckBox fx:id="showHideFileCheckBox" mnemonicParsing="false" selected="true" text="隐藏文件" />
33-
<TextField fx:id="searchDirectoryTextField" promptText="搜索文件夹" HBox.hgrow="ALWAYS" />
34-
<Button fx:id="searchDirectoryButton" mnemonicParsing="false" onAction="#searchDirectoryAction" text="浏览" />
35-
</children>
36-
</HBox>
37-
</children>
38-
</VBox>
39-
</top>
40-
<center>
41-
<TableView fx:id="searchResultTableVIew" BorderPane.alignment="CENTER">
42-
<columns>
43-
<TableColumn fx:id="fileNameTableColumn" minWidth="60.0" prefWidth="120.0" text="名称" />
44-
<TableColumn fx:id="absolutePathTableColumn" minWidth="120.0" prefWidth="240.0" text="路径" />
45-
<TableColumn fx:id="fileSizeTableColumn" maxWidth="120.0" minWidth="40.0" prefWidth="60.0" text="大小" />
46-
<TableColumn fx:id="lastModifiedTableColumn" maxWidth="200.0" minWidth="60.0" prefWidth="120.0" text="修改时间" />
47-
</columns>
48-
<BorderPane.margin>
49-
<Insets top="10.0" />
50-
</BorderPane.margin>
51-
<columnResizePolicy>
52-
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
53-
</columnResizePolicy>
54-
</TableView>
55-
</center>
56-
</BorderPane>
57-
</children>
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">
11+
<children>
12+
<BorderPane AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"
13+
AnchorPane.topAnchor="10.0">
14+
<top>
15+
<VBox spacing="5.0" BorderPane.alignment="CENTER">
16+
<children>
17+
<HBox alignment="CENTER_LEFT" spacing="5.0">
18+
<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="刷新索引"/>
25+
</children>
26+
</HBox>
27+
<HBox alignment="CENTER_LEFT" spacing="5.0">
28+
<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">
36+
<items>
37+
<FXCollections fx:factory="observableArrayList">
38+
<String fx:value="所有"/>
39+
<String fx:value="非隐藏"/>
40+
<String fx:value="隐藏文件"/>
41+
</FXCollections>
42+
</items>
43+
</ChoiceBox>
44+
<ChoiceBox fx:id="fileTypeChoiceBox" value="所有" onAction="#searchContentAction">
45+
<items>
46+
<FXCollections fx:factory="observableArrayList">
47+
<String fx:value="所有"/>
48+
<String fx:value="文件"/>
49+
<String fx:value="文件夹"/>
50+
</FXCollections>
51+
</items>
52+
</ChoiceBox>
53+
<TextField fx:id="searchDirectoryTextField" onKeyReleased="#searchContentAction"
54+
promptText="搜索文件夹" HBox.hgrow="ALWAYS"/>
55+
<Button fx:id="searchDirectoryButton" mnemonicParsing="false"
56+
onAction="#searchDirectoryAction" text="浏览"/>
57+
</children>
58+
</HBox>
59+
</children>
60+
</VBox>
61+
</top>
62+
<center>
63+
<TableView fx:id="searchResultTableVIew" BorderPane.alignment="CENTER">
64+
<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="修改时间"/>
71+
</columns>
72+
<BorderPane.margin>
73+
<Insets top="10.0"/>
74+
</BorderPane.margin>
75+
<columnResizePolicy>
76+
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
77+
</columnResizePolicy>
78+
</TableView>
79+
</center>
80+
<bottom>
81+
<HBox alignment="CENTER_LEFT" BorderPane.alignment="CENTER">
82+
<children>
83+
<Label fx:id="searchTextLabel" text="正在搜索中..."/>
84+
</children>
85+
<BorderPane.margin>
86+
<Insets top="5.0"/>
87+
</BorderPane.margin>
88+
</HBox>
89+
</bottom>
90+
</BorderPane>
91+
</children>
5892
</AnchorPane>

0 commit comments

Comments
 (0)