Lucene之二(文件操作类1-RAMDirectory)

由上一文章,我们知道Lucene中的索引库的概念,我们可以把索引库理解是一个目录,里面是一些二级制文件,就如同数据库,所有的数据也是以文件的形式存放在文件系统中的。

那么在Lucene中文件是怎么存储到索引库中,在Lucene中资源存储的API工具有哪些呢,各有什么特点?这节我们着重说说这些问题。

Lucene资源存储靠的Dircetory类(这是一个抽象类,真正实现靠其子类),在Lucene对索引文件进行读写操作时,都会调用Directory子类对应的方法。那么先列举一下Directory有哪些子类?具体结构如下

 

Directory
   --RAMDirectory
   --NRTCachingDirectory
   --FileSwitchDirectory
   --FSDirectory
       --SimpleFSDirectory
       --MmapDirectory
       --NIOFSDirectory
 

1、RAMDirectory

    RAMDirectory是将即将索引的数据资源存在在内存中而不是磁盘中,这使得文件的读写操作非常的迅速

 缺点:因为在内存中,所以在程序退出后索引数据就不存在了。

public RAMDirectory() {
    try {
      setLockFactory(new SingleInstanceLockFactory());
    } catch (IOException e) {
      // Cannot happen
    }
}

     此构造函数初始化的时候,指定的是LockFactory抽象类的一个具体实现类SingleInstanceLockFactory。SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例。

实际上,在获取到一个SingleInstanceLockFactory的实例后,那么对该目录Directory进行的所有的锁都已经获取到,这些锁都被存放到SingleInstanceLockFactory类定义的locks中。

因此,多个线程要进行加锁操作的时候,需要考虑同步问题。这主要是在获取SingleInstanceLockFactory中的SingleInstanceLock的时候,同步多个线程,包括请求加锁、释放锁,以及与此相关的共享变量。

private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
    this();
    IndexFileNameFilter filter = IndexFileNameFilter.getFilter();
    for (String file : dir.listAll()) {
      if (filter.accept(null, file)) {
        dir.copy(this, file, file);
      }
    }
    if (closeDir) {
      dir.close();
    }
  }


public RAMDirectory(Directory dir) throws IOException {
    this(dir, false);
  }
 

      这两个构造方法,就是根据一个FSDirectory进行初始化的,即在打开一个FSDirectory的时候,同时FSDirectory中的索引文件转入到RAMDirectory被创建了。

就是将指定的dir目录拷贝到当前的内存中,即实例化一个RAMDirectory。这里,closeDir是一个很重要的状态变量,指定了拷贝完成后,源目录dir是否关闭。如果实例化一个RAMDirectory完成后就关闭源目录dir,可能会因为处理的时间非常短,而需要再次打开源目录dir,持久化到文件系统目录,开销可能会比直接操作源目录dir要大,这点要权衡。

2、NRTCachingDirectory

      NRTCachingDirectory是用来在内存中缓存一些小的 segments,以减少应用对 IO的负载过高,更快速的 NRT 再次打开的效率

这个Directory子类是在Lucene3.2版本增加的。具体使用可以自己仔细研究;

猜你喜欢

转载自yufenfei.iteye.com/blog/1751613