zoukankan      html  css  js  c++  java
  • can not delete write.lock 这种错误lucene web

    这几天在学习lucene,学习过程中我首先写了一个程序,我们看一下

     1 package app;
     2 /**
    3 * @author wrh 2011/10/11
    4 */

    5 import java.io.File;
    6 import java.io.FileFilter;
    7 import java.io.FileReader;
    8 import java.io.IOException;
    9
    10 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
    11 import org.apache.lucene.analysis.standard.StandardAnalyzer;
    12 import org.apache.lucene.document.Document;
    13 import org.apache.lucene.document.Field;
    14 import org.apache.lucene.index.IndexWriter;
    15 import org.apache.lucene.store.Directory;
    16 import org.apache.lucene.store.FSDirectory;
    17 import org.apache.lucene.util.Version;
    18
    19 public class Indexer1 {
    20 private IndexWriter writer;
    21 private String indexDir = "D:\\jj";
    22
    23 public static void main(String[] args) throws Exception {
    24
    25 int numIndexed;
    26 Indexer1 indexer = new Indexer1(indexDir);
    27 System.out.println("Index begin");
    28 try {
    29 numIndexed = indexer.index(indexDir, new TextFilesFilter());
    30 System.out.println(numIndexed);
    31 } finally {
    32 indexer.close();
    33 }
    34 }
    35
    36 //constructor
    37 public Indexer1(String indexDir) throws IOException {
    38 this.indexDir = indexDir;
    39
    40 Directory dir = FSDirectory.open(new File(indexDir));
    41 writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);

    42 //writer.close();
    43 //dir.close();
    44 }
    45
    46 //close the indexwriter
    47 public void close() throws IOException {
    48 writer.close();
    49 }
    50
    51 public int index(String dataDir, FileFilter filter) throws Exception {
    52 File[] files = new File(dataDir).listFiles();
    53
    54 for (File f : files) {
    55 if (!f.isDirectory() && !f.isHidden() && f.exists() && f.canRead() &&(filter == null || filter.accept(f))) {
    56 indexFile(f);
    57 }
    58 }
    59
    60 return writer.numDocs();
    61 }
    62
    63 //filter class
    64 private static class TextFilesFilter implements FileFilter {
    65 public boolean accept(File path) {
    66 return path.getName().toLowerCase().endsWith(".txt");
    67 }
    68 }
    69
    70 //the contents of the index file
    71 protected Document getDocument(File f) throws Exception {
    72 Document doc = new Document();
    73 doc.add(new Field("contents", new FileReader(f)));
    74 doc.add(new Field("filename", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    75 doc.add(new Field("fullpath", f.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    76 return doc;
    77 }
    78
    79 private void indexFile(File f) throws Exception {
    80 System.out.println("Indexing .." + f.getCanonicalPath());
    81 Document doc = getDocument(f);
    87 writer.addDocument(doc);
    88 }
    89
    90 }


    我们将它稍加修改,把main()改名为create()部署到web上去的时候,它会报一个错误:

    can not delete writer.lock
    我们查一下lucene3.0.3的API,我们会发现这样的一段的description:

    IndexWriter

    public IndexWriter(Directory d,
    Analyzer a,
    boolean create,
    IndexWriter.MaxFieldLength mfl)
    throws CorruptIndexException,
    LockObtainFailedException,
    IOException
    Constructs an IndexWriter for the index in d. Text will be analyzed with a. If create is true, then a new, empty index will be created in d, replacing the index already there, if any.
    Parameters:
    d - the index directory
    a - the analyzer to use
    create - true to create the index or overwrite the existing one; false to append to the existing index
    mfl - Maximum field length in number of terms/tokens: LIMITED, UNLIMITED, or user-specified via the MaxFieldLength constructor.
    Throws:
    CorruptIndexException - if the index is corrupt
    LockObtainFailedException - if another writer has this index open (write.lock could not be obtained)
    IOException - if the directory cannot be read/written to, or if it does not exist and create is false or if there is any other low-level IO error

    这是什么问题呢?我们先看一下write.lock文件的作用:

    write.lock用于防止对一个索引同时进行的修改。

    IndexWriter打开的时候会获取一个write.lock,当IndexReader删除文档的时候也会获取,在它们关闭的时候会释放。

    在lucene里,如果一个writer被打开了,没有关闭另一个再希望创建一个的话它会抛出异常。

    我们上面的代码,是哪个地方在web应用中出现了问题了呢?

    第26行首先我们new了一个对象,这个对象已经开了一个IndexWriter,在constructor里,因为我们是开了一个的。

    然后我们再通过servlet调用这个create()方法的时候,还是需要new一个 IndexWriter,然后又开一个,这就矛盾了,问题出现了。也就是错误所在了。

    所以正确的合理的代码应该是这样的:

     1 package app;
    2 /**
    3 * @author wrh 2011/10/11
    4 */
    5 import java.io.File;
    6 import java.io.FileFilter;
    7 import java.io.FileReader;
    8 import java.io.IOException;
    9
    10 import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
    11 import org.apache.lucene.analysis.standard.StandardAnalyzer;
    12 import org.apache.lucene.document.Document;
    13 import org.apache.lucene.document.Field;
    14 import org.apache.lucene.index.IndexWriter;
    15 import org.apache.lucene.store.Directory;
    16 import org.apache.lucene.store.FSDirectory;
    17 import org.apache.lucene.util.Version;
    18
    19 public class Indexer1 {
    20
    21 private String indexDir = "";
    22
    23 public void create() throws Exception {
    24
    25 int numIndexed;
    26 Indexer1 indexer = new Indexer1(indexDir);
    27 System.out.println("Index begin");
    28 try {
    29 numIndexed = indexer.index(indexDir, new TextFilesFilter());
    30 System.out.println(numIndexed);
    31 } finally {
    32 System.out.println("create index must go on");
    33 }
    34 }
    35
    36 //constructor
    37 public Indexer1(String indexDir) throws IOException {
    38 this.indexDir = indexDir;
    39 }
    40
    41 public int index(String dataDir, FileFilter filter) throws Exception {
    42 File[] files = new File(dataDir).listFiles();
    43
    44 Directory dir = FSDirectory.open(new File(indexDir));
    45 IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);
    46
    47 for (File f : files) {
    48 if (!f.isDirectory() && !f.isHidden() && f.exists() && f.canRead() &&(filter == null || filter.accept(f))) {
    49
    50 System.out.println("Indexing .." + f.getCanonicalPath());
    51
    52 Document doc = getDocument(f);
    53 writer.addDocument(doc);
    54 }
    55 }
    56 writer.close();
    57 System.out.println("Create index success");
    58 return writer.numDocs();
    59 }
    60
    61 //filter class
    62 private static class TextFilesFilter implements FileFilter {
    63 public boolean accept(File path) {
    64 return path.getName().toLowerCase().endsWith(".txt");
    65 }
    66 }
    67
    68 //the contents of the index file
    69 protected Document getDocument(File f) throws Exception {
    70 Document doc = new Document();
    71 doc.add(new Field("contents", new FileReader(f)));
    72 doc.add(new Field("filename", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    73 doc.add(new Field("fullpath", f.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    74 return doc;
    75 }
    76
    77 }

    这样不要在constructor里新建一个IndexWriter,在需要的地方建,这样就可以准确的实现功能了。

    所以有的时候我们不得不考虑这些类加载过程中产生的问题与lucene本身的程序机理。



  • 相关阅读:
    IntelliJ IDEA 2016.2 配置Tomcat 运行Web项目
    关于Windows Server 服务器 安装tomcat部署Java Web 项母
    Oracle 数据库 回滚
    Oracle创建表空间、创建用户以及授权
    Kivy 简单尝试
    用qpython3写一个发送短信的程序
    PHP高效率写法
    上班时能不能戴耳机?V
    OPNsense防火墙搭建实验环境,MSF与SSH进行流量转发
    OWASP Hakcing Lab在线漏洞环境
  • 原文地址:https://www.cnblogs.com/wrh526/p/2217826.html
Copyright © 2011-2022 走看看