-- 作者:admin
-- 发布时间:2009/5/20 19:27:43
-- 程序代码——可以对Heritrix进行索引和检索的Lucene程序
import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileReader; import java.io.IOException;
import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.ScrollPaneConstants;
import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory;
//测试类 public class Exec { public static void main(String[] args) { // 创建窗体类变量 DemoWindow dw = new DemoWindow("基于Lucene的文件全文搜索系统");
// 将窗体的宽度和高度分别设置为屏幕宽度和屏幕高度的1/3,左上角位置也设置为屏幕宽度和屏幕高度的1/3处 Toolkit theKit = dw.getToolkit(); Dimension wndSize = theKit.getScreenSize(); dw.setBounds(wndSize.width / 3, wndSize.height / 3, wndSize.width / 3, wndSize.height / 3);
// 点击关闭按钮可以退出程序 dw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置窗体为可见 dw.setVisible(true); } }
// 界面窗体 class DemoWindow extends JFrame implements ActionListener { // 显示命中文件名称的文本区 JTextArea jta = new JTextArea();
// 设置文本区的滚动条 int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; JScrollPane jsp = new JScrollPane(jta, v, h);
// 菜单 JMenuBar menuBar = new JMenuBar(); JMenu index = new JMenu("建立索引"); JMenuItem indexSource = new JMenuItem("指定需要索引的目录"); JMenuItem indexDestination = new JMenuItem("指定存放索引的目录"); JMenuItem createIndex = new JMenuItem("建立索引"); JMenu search = new JMenu("搜索"); JMenuItem keywordsSearch = new JMenuItem("关键词检索");
// Lucene索引器 Indexer indexer = null;
// Lucene搜索器 Searcher searcher = new Searcher();
// 需要建立索引的文件路径 String indexSourceStr = null;
// 存放索引的路径 String indexDestinationStr = null;
// 构造函数 public DemoWindow(String title) { super(title);
// 添加文本区 add(jsp);
// 添加菜单 index.add(indexSource); index.add(indexDestination); index.addSeparator(); index.add(createIndex); search.add(keywordsSearch); menuBar.add(index); menuBar.add(search); setJMenuBar(menuBar);
// 取消部分菜单项的可用功能,这些菜单会随着操作的不断推进而逐次可用 indexDestination.setEnabled(false); createIndex.setEnabled(false); keywordsSearch.setEnabled(false);
// 添加事件监听器 indexSource.addActionListener(this); indexDestination.addActionListener(this); createIndex.addActionListener(this); keywordsSearch.addActionListener(this); }
// 响应单击菜单 public void actionPerformed(ActionEvent e) { // 设置需要建立索引的文件所在目录 if (e.getSource() == indexSource) { // 设置文件选择对话框 JFileChooser jfc = new JFileChooser();
// 该文件选择对话框只能打开文件目录 jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { // 将“指定存放索引的目录”菜单项设置为可用 indexDestination.setEnabled(true);
// 保存需要建立索引的文件路径 indexSourceStr = jfc.getSelectedFile().getPath(); } } // 设置保存索引的目录 else if (e.getSource() == indexDestination) { // 设置文件选择对话框 JFileChooser jfc = new JFileChooser();
// 该文件选择对话框只能打开文件目录 jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if (jfc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { // 将“建立索引”菜单项设置为可用 createIndex.setEnabled(true);
// 保存存放索引的路径 indexDestinationStr = jfc.getSelectedFile().getPath(); } } // 处理建立索引 else if (e.getSource() == createIndex) { // 建立索引器类变量 indexer = new Indexer(indexSourceStr, indexDestinationStr);
// 在新线程中建立索引 Thread t = new Thread(new ProcessIndex(indexer, keywordsSearch)); t.start(); } // 处理搜索 else if (e.getSource() == keywordsSearch) { // 显示输入信息对话框 String queryWords = JOptionPane.showInputDialog("请输入搜索词语:");
// 在文本区输出命中的文件名称结果 jta.setText(searcher.getResults(queryWords, indexDestinationStr)); } } }
// 建立索引的线程(由于索引比较耗时,所以单独使用一个线程来建立索引) class ProcessIndex implements Runnable { // 索引器类变量 Indexer indexer;
// 当索引结束后,设置该菜单项可用 JMenuItem jmi;
// 构造函数 public ProcessIndex(Indexer indexer, JMenuItem jmi) { this.indexer = indexer; this.jmi = jmi; }
// 线程的工作方法,启动索引工作,并在索引建立后,设置该菜单项可用 public void run() { try { indexer.start(); jmi.setEnabled(true); } catch (Exception e) { System.out.println(e.getMessage()); } } }
// 索引器 class Indexer { // 需要建立索引的文件路径 String indexSourceStr;
// 存放索引的路径 String indexDestinationStr;
// 构造函数 public Indexer(String indexSourceStr, String indexDestinationStr) { this.indexSourceStr = indexSourceStr; this.indexDestinationStr = indexDestinationStr; }
// 调用index建立索引的函数 public void start() { try { File dataDir = new File(indexSourceStr); File indexDir = new File(indexDestinationStr); index(indexDir, dataDir); } catch (Exception e) { System.out.println(e.getMessage()); } }
// 调用indexDirectory函数建立索引的函数 public void index(File indexDir, File dataDir) throws IOException { // 建立索引写入器 // indexDir表示索引的存放地点 // new StandardAnalyzer()表示分析器 // true表示如已有索引则覆盖之 IndexWriter writer = new IndexWriter(indexDir, new StandardAnalyzer(), true);
// 表示生成多文件索引文件(默认为复合索引) writer.setUseCompoundFile(false);
// 递归调用indexDirectory函数 indexDirectory(writer, dataDir);
// 优化索引 writer.optimize(); writer.close(); }
// 被递归调用的建立索引函数 private void indexDirectory(IndexWriter writer, File dir) throws IOException { // 得到文件列表 File[] files = dir.listFiles();
// 循环所有文件 for (int i = 0; i < files.length; i++) { File f = files[i];
// 如果是目录,则递归调用自己,否则如果文件扩展名为html,则调用indexFile函数对此文件建立索引 if (f.isDirectory()) { indexDirectory(writer, f); } else if (f.getName().endsWith(".html")) { indexFile(writer, f); } } }
// 对指定文件建立索引的函数 private void indexFile(IndexWriter writer, File f) throws IOException { // 如果文件隐藏、不存在或者不可读取,则退出函数 if (f.isHidden() || !f.exists() || !f.canRead()) { return; }
// 在控制台输出建立索引的文件信息 System.out.println("Indexing " + f.getCanonicalPath());
// 建立索引关键代码 // 建立Document类变量 Document doc = new Document();
// 添加contents索引字段,内容为文件内容 doc.add(Field.Text("contents", new FileReader(f)));
// 添加url索引字段,内容为文件名称 String filename = f.getCanonicalPath(); String url = filename.substring(filename.lastIndexOf("mirror") + 7); doc.add(Field.Keyword("url", url));
// 写入索引 writer.addDocument(doc); } }
// 搜索器 class Searcher { // 根据搜索词和索引文件路径进行搜索的函数 public String getResults(String queryWords, String indexDestinationStr) { // 返回结果 StringBuffer results = new StringBuffer();
try { // 打开索引 File indexDir = new File(indexDestinationStr); Directory fsDir = FSDirectory.getDirectory(indexDir, false); IndexSearcher is = new IndexSearcher(fsDir);
// 解析查询词语 Query query = QueryParser.parse(queryWords, "contents", new StandardAnalyzer()); // Query query = new TermQuery(new Term("contents", "java")); // Query query = new TermQuery(new Term("contents", "application")); // Query query = new TermQuery(new Term("contents", "java AND NOT // application"));
// 搜索索引 Hits hits = is.search(query);
// 输出搜索结果 for (int i = 0; i < hits.length(); i++) { Document doc = hits.doc(i); results.append(doc.get("url") + "\\n"); } } catch (Exception e) { System.out.println(e.getMessage()); } return results.toString(); } }
[此贴子已经被作者于2010-12-14 09:40:18编辑过]
|