1. 私のオリジナルプログラム
実際、私の元のプログラムは非常に単純で、デモの SearchFiles と IndexFiles を完全に変更したものでした。唯一の違いは、SmartCN トークナイザーを参照していることです。
その点を修正したコードを載せておきます。
インデックスh中国語.java:
Date start = new Date();try { IndexWriter ライター = new IndexWriter(FSDirectory.open(INDEX_DIR), new Smart ChineseAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED); .println("ディレクトリへのインデックス作成中 '" +INDEX_DIR+ "'..."); System.out.println("最適化中..."); //writer.close(); new Date(); System.out.println(end.getTime() - start.getTime() + "合計ミリ秒");
検索中国語.java
アナライザーanalyzer = new Smart ChineseAnalyzer(Version.LUCENE_CURRENT); in = null;if (queries != null) { in = new BufferedReader(new FileReader(queries));} else { in = new BufferedReader(new InputStreamReader(System.in) 、「GBK」));}
ここでは、入力クエリが GBK でエンコードされることを指定します。
それで安心して実行してみたところ…中国語は取得できず、内部の英語の取得は正常であることがわかりました。
2. 問題を見つけます。
それで、私は Java と Lucene に慣れすぎていたのと、使用していた 3.0.0 バージョン以外の議論があまりなかったため、落ち込んでしまい、しばらくいじってみたところ、ファイルを保存すれば取り出せることがわかりました。 ansi 形式で、中国語です (以前は UTF-8 でした)。少し検索したところ、index Chinese.java に次のコードが見つかりました。
static void indexDocs(IndexWriter Writer, File file) throws IOException { // 読み取れないファイルのインデックス作成は行わない if (file.canRead()) { if (file.isDirectory()) { String[] files = file. list(); // (files != null) { for (int i = 0; i < files.length; i++) {indexDocs(writer, new File(file, files[i])) の場合、IO エラーが発生する可能性があります; } } } else { System.out.println("adding " + file); try {writer.addDocument(FileDocument.Document(file)) } // 少なくとも Windows では、一部の一時ファイルでこの例外が発生します。アクセスが拒否されました" メッセージ // ファイルが読み取れるかどうかをチェックしても catch (FileNotFoundException fnfe) { ; } } }
重要なポイントは次の一文です。
{writer.addDocument(FileDocument.Document(file));} を試してください。
ファイルを読み取るためのコードはここにあるはずです。それをトレースします。
public static Document Document(File f) throws java.io.FileNotFoundException, UnsupportedEncodingException { Document doc = new Document(); doc.add(new Field("path", f.getPath(), Field.Store.YES, Field. Index.NOT_ANALYZED)); doc.add(new Field("modified", DateTools.timeToString(f.lastModified(), DateTools.Resolution.MINUTE), Field.Store.YES, Field.Index.NOT_ANALYZED)); add(new Field("contents", FileReader(f))); // ドキュメントを返します return doc;} private FileDocument() {}}
これは Lucene の内部クラスです。その機能は、テキスト ファイルからコンテンツを取得することです。生成される Document には、デフォルトで、path、modified、content の 3 つのフィールドがあり、content はファイルのテキスト コンテンツであるようです。 f)、この関数には問題がありました。読み取りに使用するエンコーディングが指定されていなかったので、ここで修正しました。
FileInputStream fis=new FileInputStream(f);//UTF-8 エンコーディングに従ってバイト ストリームを文字ストリームに変換する InputStreamReader isr=new InputStreamReader(fis,"UNICODE");//文字ストリームからテキストを取得し、バッファリングする BufferedReader br=new BufferedReader(isr); doc.add(new Field("contents", br));
「Unicode」については、サポートされているすべてのエンコードに変更できますが、「utf-8」に変更したところ、正常に使用できました。
3. いくつかの推測:
Lucene でファイルのインデックスを作成する場合、エンコードが正しく指定されていれば、出力ファイルは正常に取得できます。つまり、異なるエンコード ファイルのインデックスを作成した後の結果は同じになります (検証)。