目录
1. 需求分析
2. 系统设计
主要类
3. Java代码实现
4. 进一步扩展
在Java中实现一个简单的本地搜索功能的设计流程通常包括以下几个步骤:
1. 需求分析
- 输入:用户输入要索引的目录路径和搜索的关键词。
- 处理:
- 扫描指定目录及其子目录,读取文件内容并建立索引。
- 根据用户输入的关键词在索引中查找匹配的文件。
- 输出:展示匹配文件的列表。
2. 系统设计
主要类
- FileIndexer:负责扫描目录和建立索引。
- FileSearcher:负责根据关键词进行搜索。
- SearchResult:表示搜索结果(可以选择性实现)。
- Main:程序入口,包含用户交互逻辑。
3. Java代码实现
这段代码实现了一个简单的文件索引和搜索程序,用户可以输入目录路径,程序会索引该目录中的所有文件,并允许用户通过关键字搜索文件内容。
分为三个主要类:FileIndexer
、FileSearcher
和Main
。下面是对每个部分的详细分析:
(1)创建一个FileIndexer类,负责读取指定目录下的所有文件,并将文件内容索引到一个Map
中,键为文件的绝对路径,值为文件内容。
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
/**
* @author water
* @date 2024/10/5
*/
public class FileIndexer {
private Map<String, String> index = new HashMap<>();
// 构建索引
public void indexFiles(String directoryPath) {
try {
File directory = new File(directoryPath);
if (!directory.isDirectory()) {
throw new IllegalArgumentException("Provided path is not a directory");
}
indexDirectory(directory);
} catch (Exception e) {
System.err.println("Error indexing files: " + e.getMessage());
}
}
// 递归索引目录
private void indexDirectory(File directory) {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
indexDirectory(file); // 递归索引子目录
} else {
indexFile(file);
}
}
}
// 索引单个文件
private void indexFile(File file) {
try {
String content = new String(Files.readAllBytes(file.toPath()));
index.put(file.getAbsolutePath(), content); // 使用文件绝对路径作为索引
} catch (IOException e) {
System.err.println("Failed to read file: " + file.getAbsolutePath());
}
}
public Map<String, String> getIndex() {
return index;
}
}
一个 Map<String, String> index
,用于存储文件名和文件内容的映射关系。
indexFiles(String directoryPath)该方法接收一个目录路径作为参数,并尝试对该目录中的文件进行索引。首先创建一个 File
对象并检查该路径是否是一个目录。如果不是,则抛出 IllegalArgumentException
。调用 indexDirectory(File directory)
方法来索引该目录。使用 try-catch
捕获异常并打印错误信息。
indexDirectory(File directory)
方法遍历目录中的所有文件和子目录。如果遇到子目录,则递归调用自身来索引子目录。如果遇到文件,则调用 indexFile(File file)
方法进行索引。
indexFile(File file)
方法读取文件的内容并将文件名和内容存入 index
中。使用 Files.readAllBytes()
方法读取文件内容,并将其转换为字符串。如果文件读取失败,捕获 IOException
异常并打印错误信息。
getIndex()
方法主要是用来返回当前索引的 Map
。
(2)创建一个FileSearcher类,接受一个索引并根据用户输入的关键词进行搜索,返回匹配的文件路径及其内容。
import java.util.HashMap;
import java.util.Map;
/**
* @author water
* @date 2024/10/5
*/
public class FileSearcher {
private Map<String, String> index;
public FileSearcher(Map<String, String> index) {
this.index = index;
}
// 根据关键词搜索
public Map<String, String> search(String keyword) {
Map<String, String> results = new HashMap<>();
for (Map.Entry<String, String> entry : index.entrySet()) {
if (entry.getValue().toLowerCase().contains(keyword.toLowerCase())) {
results.put(entry.getKey(), entry.getValue());
}
}
return results;
}
}
index
变量用来存储在 FileIndexer
中生成的文件索引。
FileSearcher(Map<String, String> index)
构造函数,接收一个索引 Map
,并将其存储到 index
属性中。
search(String keyword)
方法接收一个关键字作为参数,返回一个 Map<String, String>
类型的搜索结果。遍历索引中的每个条目,检查文件内容是否包含关键字(不区分大小写),如果找到匹配项,则将其加入结果 Map
中。
(3)创建一个Main类,提供用户界面,读取用户输入,调用索引和搜索功能,最后输出搜索结果。
import java.util.Map;
import java.util.Scanner;
/**
* @author water
* @date 2024/10/5
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
FileIndexer indexer = new FileIndexer();
// 指定要索引的目录
System.out.println("Enter the directory to index:");
String directoryPath = scanner.nextLine();
System.out.println("You entered: " + directoryPath); // 调试输出
// 进行搜索
System.out.println("Enter a keyword to search:");
String keyword = scanner.nextLine();
indexer.indexFiles(directoryPath);
Map<String, String> index = indexer.getIndex();
System.out.println(index.toString());
FileSearcher searcher = new FileSearcher(index);
Map<String, String> results = searcher.search(keyword);
System.out.println(results.toString());
// 展示搜索结果
if (results.isEmpty()) {
System.out.println("No results found.");
} else {
System.out.println("Search Results:");
for (String fileName : results.keySet()) {
System.out.println("File: " + fileName);
}
}
scanner.close(); // 关闭Scanner以释放资源
}
}
创建 Scanner
对象用于读取用户输入。然后,创建 FileIndexer
对象以索引文件,提示用户输入目录路径并读取该路径。调用 indexFiles
方法对该目录进行索引,并获取索引结果。
提示用户输入关键字进行搜索。创建 FileSearcher
对象,并调用 search
方法来查找包含该关键字的文件。
最后,打印搜索结果。如果结果为空,则提示用户未找到结果。
(4)在本地的路径D:\my\else\code-learning\python-study下,目录结构如下所示:
其中,D:\my\else\code-learning\python-study\t.txt这个文件的内容如下,
代码执行结果如下,
确保使用有效的路径输入,例如在Windows中使用C:\\Users\\YourUsername\\Documents
,在Unix/Linux中使用/home/yourusername/documents
。如果输入路径后程序没有响应,注意检查控制台输出的任何错误消息。
4. 进一步扩展
- 多线程:可以实现多线程索引和搜索,以提高性能。
- 图形用户界面(GUI):使用Swing或JavaFX创建更友好的用户界面。
- 更复杂的搜索:支持正则表达式搜索、模糊匹配等功能。