1. 내 원래 프로그램
사실 내 원래 프로그램은 데모의 SearchFiles 및 IndexFiles에서 완전히 수정되어 매우 간단했습니다. 유일한 차이점은 SmartCN 토크나이저를 참조했다는 것입니다.
그 점을 수정한 코드를 게시하겠습니다.
Indexh중국어.java:
날짜 시작 = new Date();try { IndexWriter 작가 = new IndexWriter(FSDirectory.open(INDEX_DIR), new SmartChinaAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED); indexDocs(writer, docDir); .println("인덱싱 중'" +INDEX_DIR+ "'..."); System.out.println("최적화 중..."); //writer.optimize(); new Date(); System.out.println(end.getTime() - start.getTime() + "총 밀리초");
검색중국어.java
분석기 분석기 = new SmartChinaAnalyzer(Version.LUCENE_CURRENT); BufferedReader 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이었습니다.) 파일 인코딩 문제인 것 같습니다.
static void indexDocs(IndexWriterwriter, File file) throws IOException { // 읽을 수 없는 파일의 인덱스를 시도하지 마세요. if (file.canRead()) { if (file.isDirectory()) { String[] files = file. list(); // IO 오류가 발생할 수 있는 경우 (files != null) { for (int i = 0; i < files.length; i++) { indexDocs(writer, new File(file, files[i])) ; } } } else { System.out.println("adding " + file); try {writer.addDocument(FileDocument.Document(file)) } // 적어도 Windows에서는 일부 임시 파일에서 " 접근 거부됨" 메시지 // 파일을 읽을 수 있는지 확인하는 것은 도움이 되지 않습니다. (FileNotFoundException fnfe) { ; } } }
핵심은 이 문장이다.
시도 { 작가.addDocument(FileDocument.Document(파일));}
파일을 읽는 코드는 여기에 있어야 합니다. 추적하세요.
공용 정적 문서 문서(파일 f)는 java.io.FileNotFoundException, UnsupportedEncodingException { Document doc = new Document(); 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의 내부 클래스입니다. 생성된 문서에는 기본적으로 경로, 수정됨, 내용이라는 세 가지 필드가 있으며 파일의 텍스트 내용인 것 같습니다. 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에서 파일을 인덱싱할 때 인코딩은 중요하지 않습니다. 올바르게 지정하면 출력 파일을 정상적으로 검색할 수 있습니다. 즉, 다른 인코딩 파일을 인덱싱한 후의 결과는 동일합니다(검증).