Lucene简单例子,快速检索D盘内容(java)

第一次写博文,有错误请多指教。
在这里我用的是Lucene 3.0.2的包
这两天都在复习Lucene,因为要考试,复习的无聊之际,就尝试写个来检索D盘的简单的搜索引擎。
我们都知道,Lucene是一个,是一个开放源代码的全文检索引擎工具包,有了这个,我们就可干很多事情,比如简单的搜索引擎什么的,Lucene的效率很高。网上也有很多教程,大家可以上网查查这方面有关的资料。
接下来我就介绍下我的思路。
首先我们要获取D盘所有文件的基本信息,在这里我是获取了文件的文件名,还有文件的路径作为lucene的数据源。在这里我用了个多线程遍历整个D盘的文件。多线程的思路来源就是前几天老师教的那个多线程下载文件,比以前写的单线程快多了。
代码如下:

package visitUtil; 

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/** 
 * @ClassName:     LookAndVisitFile.java
 * @author 作者姓名  Lin: email地址 
 * @version 创建时间:2016-1-6 下午2:53:40 
 * @Description TODO
 */
public class LookAndVisitFile {
    String  path = "D://";//遍历的路径
    RandomAccessFile inxfile = null;
    File file = null;
    //遍历文件。并把文件信息写到D:/temp下.txt(内容包括文件名称,文件绝对路径)
    public synchronized void visit(String path) throws IOException{
        inxfile = new RandomAccessFile("D:/temp.txt","rw");
        file = new File(path);
        if(file.isDirectory()){
            inxfile.seek(inxfile.length());
            inxfile.writeChars(new String(file.getName().getBytes("gbk"),"gbk").trim()+","+new String(file.getAbsolutePath().getBytes("gbk"),"gbk")+","+file.lastModified()+"\r\n");                    
            binaryVisit(file.listFiles(),3);
        }
        else if(file.isFile()){     
            //写入文件信息
                inxfile.seek(inxfile.length());
                inxfile.writeChars(new String(file.getName().getBytes("gbk"),"gbk").trim()+","+new String(file.getAbsolutePath().getBytes("gbk"),"gbk")+","+file.lastModified()+"\r\n");                    
        }
        inxfile.close();
    }   
    /**
     * 
     * @param files 目录下的多个文件
     * @param num  线程的数量
     */
    //遍历文件 
    private void binaryVisit(File[] files,int num) {
        final int block = files.length/num;

        for (int i = 1; i <= num; i++) {
            int start = (i-1)*block;//计算文件遍历的起始位置
            int end = i*block;//文件文件的结束位置
            System.out.println(Thread.currentThread()+":=start="+start+":end="+end);
            if((start-end)==0)continue;//加了个coninue速度快了一大截
            startThread(files,start,end);

        }
    }
    public void startThread(final File[] files,final int start,final int end){
        new Thread(new Runnable() {         
                    @Override
                    public void run() {
                        for (int j = start; j < end; j++) {
                            try {
                                Thread.sleep(100);
                                //System.out.println(files[j].getAbsolutePath());
                                visit(files[j].getAbsolutePath());//
                            } catch (IOException e) {
                                e.printStackTrace();
                            }catch (Exception e) {
                                e.printStackTrace();
                            }
                        }                       
                    }
        }).start();

    }

    public static void main(String[] args) throws IOException {
        new LookAndVisitFile().visit("D://");
    }
}

Lucene搜索部分

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
/** 
 * @ClassName:     TestLucene.java
 * @author 作者姓名  Lin: email地址 
 * @version 创建时间:2016-1-6 下午3:57:28 
 * @Description TODO
 */
public class TestLucene {
    //表示索引的存放目录
    String path = "D:/LuceneTestDircetory";//索引存放的目录位置,要先创建此文件夹
    //
    Directory dir;
    public List<String[]> readFile(String filepath) throws Exception{
        File file = new File(filepath);

        List<String[]>sts = new ArrayList<String[]>();
        //字符流读文件
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-16"));//打开的格式用UTF-16的格式打开,才不会乱码,这个与前面写入文件的时候的格式有关
        String line = null;
        //每次读取一行就对文件的信息作出相应的解析 格式在写进文件的时候要确定好,在这里我是用,隔开信息
        //本来想用Map值来存储,但是用List存放信息,更快
        while((line=reader.readLine())!=null){   
            String[] temp;
            temp = line.split(",");
            if(temp.length==3)
            {
                sts.add(temp);
            }

        }
        return sts;
    }
    //@Test
  /*  public void testxxx() {
        try {
            //String t = "`)0B0CBIY@A5}Q(ESKZS24G.jpg^D:\DataBackup\Tencent\494341886\Image\Image2\`)0B0CBIY@A5}Q(ESKZS24G.jpg^1374504260426"

                    readFile("D:\\temp.txt");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }*/
    //创建索引,并添加Document
    public void createIndex() throws Exception{
        System.out.println(path);
        dir = FSDirectory.open(new File(path));
        IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true ,MaxFieldLength.UNLIMITED);
        List s = readFile("D://temp.txt");
        for (int i = 0; i < s.size(); i++) {
            Document doc = new Document();          
            doc.add(new Field("filename", ((String[])s.get(i))[0],Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
            doc.add(new Field("filepath", ((String[])s.get(i))[1],Store.YES,Field.Index.ANALYZED_NO_NORMS));
            doc.add(new Field("filetime", ((String[])s.get(i))[2],Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
            writer.addDocument(doc);
        }
        writer.close();     
    }

    //搜索部分
    //这里主要是通过文件名,进行检索,大家可以用Reader()类对文本内容进行检索
    public void Seacher(String keyword) throws Exception{
        dir = FSDirectory.open(new File(path));//打开存放目录
        IndexReader red = IndexReader.open(dir);//获取reader类
        IndexSearcher searcher = new IndexSearcher(red);//获取检索类
        QueryParser parse = new QueryParser(Version.LUCENE_30, "filename", new StandardAnalyzer(Version.LUCENE_30));
        Query query = parse.parse(keyword+"~");
        TopDocs docs = searcher.search(query, 1000);
        //如果相似相似项找不到,就用通配符进行检索
        if(docs.totalHits==0){
            query = parse.parse(keyword+"*");
            docs = searcher.search(query, 1000);
            if(docs.totalHits==0){
                System.out.println("找不到此类文件");
                return ;
            }
        }

        for (int i = 0; i < docs.totalHits; i++) {
            System.out.println("文件名:"+searcher.doc(docs.scoreDocs[i].doc).get("filename")+"     路径是:"+searcher.doc(docs.scoreDocs[i].doc).get("filepath"));
            SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String time = sFormat.format(new Date(Long.parseLong(searcher.doc(docs.scoreDocs[i].doc).get("filetime"))));
            System.out.println("最后修改日期:"+time);

        }
        red.close();
        searcher.close();

    }
    public static void main(String[] args) {
        long startime = System.currentTimeMillis();
        try {
            //new TestLucene().testxxx();
            //new TestLucene().createIndex();
            new TestLucene().Seacher("火");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long endtime = System.currentTimeMillis();
        System.out.println("花费是时间是:"+(endtime-startime)+"ms");
    }

}

[程序搜索运行的结果如下]
程序检索运行的结果如下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值