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本身的程序机理。



  • 相关阅读:
    AtCoder Tenka1 Programmer Beginner Contest 解题报告
    BZOJ4401: 块的计数 思维题
    LOJ#2170. 「POI2011」木棍 Sticks
    LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On
    LuoguP3183 [HAOI2016]食物链 记忆化搜索
    BZOJ2818: Gcd 欧拉函数
    BZOJ3942: [Usaco2015 Feb]Censoring 栈+KMP
    适用于Java的嵌入式脚本语言
    oracle goldengate的两种用法
    手滑把库给删了,跑路前应该做的事。。。
  • 原文地址:https://www.cnblogs.com/wrh526/p/2217826.html
Copyright © 2011-2022 走看看