Tips 示例代码基于Lucene 6.2.1.
Directory
创建索引时,必须要用到,而它只有一个构造函数:
public IndexWriter(Directory d, IndexWriterConfig conf)
这里的Directory是必须的。
Directory是Lucene内部自定义的目录类型,它本身是一个抽象类,在Lucene自带的工具包中,Directory有两个子类,分别是RAMDirectory和FSDirectory。
从名称上可以知道,FSDirectory与系统文件有关,而RAMDirectory和系统内存有关。之所以有这两种形式,和它们在不同情形下的优势有关。
RAMDirectory
RAMDirectory是内存中的一个区域,只需要简单的使用构造函数就可以得到其实例。
Directory directory = new RAMDirectory();
它默认通过SingleInstanceLockFactory(单实例锁工厂)进行锁的实现。该类适用于小量的常驻内存索引,不适合大量索引的情况,也不适用于多线程的情况。
RAMDirectory带来的好处就是高效率,而过大的索引文件会到时内存不足。
FSDirectory
一般代码中,使用下面的方式获取FSDirectory实例。
Directory directory = FSDirectory.open(Paths.get("d://myindex"));
这里使用open()方法是为了达到最佳实现方式:
public static FSDirectory open(Path path, LockFactory lockFactory) throws IOException {
if (Constants.JRE_IS_64BIT && MMapDirectory.UNMAP_SUPPORTED) {
return new MMapDirectory(path, lockFactory);
} else if (Constants.WINDOWS) {
return new SimpleFSDirectory(path, lockFactory);
} else {
return new NIOFSDirectory(path, lockFactory);
}
}
它默认通过NativeFSLockFactory(本地文件锁工厂)进行锁的实现。
在诸如Linux, MacOSX, Solaris和windows 64位操作系统的JRE中,使用MMapDirectory方式,在其他非windows操作系统的JRE中,使用NIOFSDirectory方式,其他windows操作系统的JRE中,使用SimpleFSDirectory方式。当然,如果你自己的服务确定在某种环境下使用,可以这样指定实现方式:
Directory directory = MMapDirectory.open(Paths.get("d://myindex"));
为什么有这么多实现版本也是因为它们有各自的特点:
- SimpleFSDirectory:FSDirectory的简单实现,并发能力有限,遇到多线程读同一个文件时会遇到瓶颈
- NIOFSDirectory:通过java.nio’s FileChannel实行定位读取,支持多线程读(默认情况下是线程安全的)。该类仅使用FileChannel进行读操作,写操作则是通过FSIndexOutput实现。 注意:NIOFSDirectory 不适用于Windows系统,另外如果一个访问该类的线程,在IO阻塞时被interrupt或cancel,将会导致底层的文件描述符被关闭,后续的线程再次访问NIOFSDirectory时将会出现ClosedChannelException异常,此种情况应用SimpleFSDirectory代替。
- MMapDirectory:通过内存映射进行读,通过FSIndexOutput进行写的FSDirectory实现类。使用该类时要保证用足够的虚拟地址空间。另外当通过IndexInput的close方法进行关闭时并不会立即关闭底层的文件句柄,只有GC进行资源回收时才会关闭。
Direcotry相关类
FileSwitchDirectory
文件切换的Directory实现.针对lucene的不同的索引文件使用不同的Directory .借助FileSwitchDirectory整合不同的Directory实现类的优点于一身
RateLimitedDirectoryWrapper
通过IOContext来限制读写速率的Directory封装类。
CompoundFileDirectory
用于访问一个组合的数据流。仅适用于读操作。对于同一段内扩展名不同但文件名相同的所有文件合并到一个统一的.cfs文件和一个对应的.cfe文件内。
TrackingDirectoryWrapper
Directory的代理类。用于记录哪些文件被写入和删除。