B. FileNotFoundException:虽然在工厂中是将文件先获取路径然后再传给下面的解析器,但各文本类型解析器还是要对文件是否存在的异常进行判断。调用第三方包的时候容易产生该异常,如:在OfficeReader的解析过程中POITextExtractor extractor = ExtractorFactory.createExtractor(file),该函数容易产生该异常。
C. BadLocationException:该异常的目的是报告文档模型中的损坏位置,即试图引用一个不存在的位置。程序中RtfReader中new RTFEditorKit().read(fis,styledDoc,0)将有可能产生该异常。
3.1.6 遇到的问题及解决的方案
在进行文件解析模块开发的时候,就会经常的去考虑如何去进行解析,以及word和pdf类文档的解密问题如何处理。
开始的时候通过查阅资料了解到pdf的文件格式,pdf文件主要的文件结构分为四个部分:首部、文件体、交叉引用表以及尾部。
图3.1.6.1 PDF文件的物理结构
解析pdf文件时应该先程序首先访问文件尾,从文件尾中找到交叉引用表的地址以及PDF文件的Catalog根节点。然后通过读取交叉引用表中的地址,读取PDF文档中的间接对象读取整个PDF文档的内容。
虽然可以通过以上的文件结构和解析的顺序方法得到PDF文档的内容,但是相对麻烦,如果每个文本解析器都从底层了解结构写起真的在时间上是不允许的,所以这里面可以采用第三方的包解决这个问题,即pdfbox。
Pdfbox在使用的时候只需要先定义一个该文件的FileInputStream,然后将该输入流传递给PDFParser由它获取pdfdocument,这样就获得了一个pdfdocument的对象,然后通过建立pdfstripper取得getText方法获取文本内容,简单适用。
其次就是封装的时候采取了工厂模式的开发代替了原有的那种很裸的不规范的面向对象开发,这使我对软件开发的原则有了更深的认识。
3.2 分词索引模块
3.2.1 主要功能
该模块主要是为被索引文件建立索引的模块,其中包括分词以及索引,索引的时候调用上述文件解析模块,对文本的内容进行解析,然后将该文本内容进行分词,根据分词结果建立索引,这就是该模块主要实现的功能。既然要建立索引,那么首先要做的任务就是扫描硬盘。因此扫描硬盘的工作也放在了该模块实现。
3.2.2 设计思想
该模块首先是对本地磁盘进行扫描,扫描过程可以采用递归的方式对磁盘系统进行深度优先搜索,每搜索到一个路径之后,判断一下该路径是一个文件的路径还是一个目录的路径,即文件夹路径,如果是文件夹路径,则以此为起点再向下搜索。否则如果是文件的话,那么根据之前指定好的不同的索引规则,判断是否是隐藏文件,判断是否是“常规”文件,最后如果文件是属于可解析的文件的话便可以将文件传给底层的文本解析模块,文本解析模块将解析出来的内容重新传给该模块。然后该模块将返回的文本内容进行分词然后以分词的结果为key创建好索引即可。
根据以上的流程可以分析解决方法:
对于文件系统的扫描首先输入中对建立索引的策略进行分析,选择是否扫描隐藏文件和非常规文件。这里writer = new IndexWriter(indexDir, new StandardAnalyzer(), true);定义一个索引书写器,通过File.listRoots()列出磁盘的分区,通过找到特定磁盘上的路径之后file.isDirectory()如果为真则路径是一个文件夹,否则是一个文件,如果是文件夹则递归处理,否则createIndex(file)创建索引。
创建索引的地方可以通过lucene提供的索引进行创建。其中要使用到lucene中的Field类。有关Field的几种不同的静态方法定义如下: Lucene桌面搜索引擎的设计与实现(6):http://www.751com.cn/jisuanji/lunwen_7560.html