我正在使用 Lucene 4.6,并且显然不清楚如何重用 TokenStream,因为我得到了异常:

java.lang.IllegalStateException: TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.

在第二轮开始时。我已经阅读了 Javadoc,但我仍然缺少一些东西。这是一个抛出上述异常的简单示例:
@Test
public void list() throws Exception {
  String text = "here are some words";
  TokenStream ts = new StandardTokenizer(Version.LUCENE_46, new StringReader(text));
  listTokens(ts);
  listTokens(ts);
}

public static void listTokens(TokenStream ts) throws Exception {
  CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
  try {
    ts.reset();
    while (ts.incrementToken()) {
      System.out.println("token text: " + termAtt.toString());
    }
    ts.end();
  }
  finally {
    ts.close();
  }
}

我试过不调用 TokenStream.end()TokenStream.close() 认为也许它们应该只在最后调用,但我得到了同样的异常(exception)。

任何人都可以提供建议吗?

最佳答案

Exception 列出了多次调用 reset() 的可能问题,这是您正在做的。这在 Tokenizer 的实现中是明确不允许的。由于 java.io.Reader api 不保证所有子类都支持 reset() 操作,因此 Tokenizer 不能假设传入的 Reader 毕竟可以重置。

您可以简单地构造一个新的 TokenStream,或者我相信您可以调用 Tokenizer.setReader(Reader)(在这种情况下,您当然必须先对其进行 close())。

10-08 19:56