RAMDirectory是Directory抽象类在使用内存最为文件存储的实现类,其主要是将所有的索引文件保存到内存中。这样可以提高效率。但是如果索引文件过大的话,则会导致内存不足,因此,小型的系统推荐使用,如果大型的,索引文件达到G级别上,推荐使用FSDirectory
首先我们看看该类的源代码:
首先该类继承与抽象类Directory,并且实现了序列话接口
1
/** */
/**一个对于Directory的内存实现的类,锁工厂是有SingleInstanceLockFactory来实现,但是锁工厂可以更改 */
2 public class RAMDirectory extends Directory implements Serializable {
3 private static final long serialVersionUID = 1l;
4 HashMap fileMap = new HashMap(); //首先定了保存文件名以及的Map
5 long sizeInBytes = 0; //文件占用的字节数
6 /** *//** 构造函数。指定LockFactory为该类的一个实例SingleInstanceLockFactory,SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例*/
7 public RAMDirectory() {
8 setLockFactory(new SingleInstanceLockFactory());
9 }
10 /** *//** 定义一个新的RAMDirectory,并且指定其目录,这个做的目的可以将一个文件系统的索引加载到内存中,这个只能使用在该索引能够被全部加在到内存中。这次只是将系统文件的索引拷贝一份到内存中,加载后,系统文件索引发生变化,将不会在该实例中体现。 */
11 public RAMDirectory(Directory dir) throws IOException {
12 this(dir, false);
13 }
14 /** *//** 根据目录,以及参数将该目录中的所有文件复制到内存中,需要复制的文件已经存在,则直接覆盖。closeDir表示是否关闭源目录*/
15 private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
16 this();
17 Directory.copy(dir, this, closeDir);
18 }
19 /** *//**根据提供的文件路径,将该文件路径下的所有的文件复制到内存中,并且创建一个RAMDirectory对象。如果需要复制的对象已经存在,则覆盖原来的文件*/
20 public RAMDirectory(File dir) throws IOException {
21 this(FSDirectory.getDirectory(dir), true);
22 }
23/** *//**根据提供的String路径,将该文件路径下的所有的文件复制到内存中,并且创建一个RAMDirectory对象。如果需要复制的对象已经存在,则覆盖原来的文件*/
24 public RAMDirectory(String dir) throws IOException {
25 this(FSDirectory.getDirectory(dir), true);
26 }
27 /** *//**返回所有该文件该内存索引中的所有文件 */
28 public synchronized final String[] list() {
29 ensureOpen();
30 Set fileNames = fileMap.keySet(); //该文件的所有key
31 String[] result = new String[fileNames.size()];
32 int i = 0;
33 Iterator it = fileNames.iterator();
34 while (it.hasNext())
35 result[i++] = (String)it.next();
36 return result;
37 }
38 /** *//**如果指定文件名的文件在索引中存在,则返回true,否则返回false*/
39 public final boolean fileExists(String name) {
40 ensureOpen();
41 RAMFile file;
42 synchronized (this) {
43 file = (RAMFile)fileMap.get(name);
44 }
45 return file != null;
46 }
47/** *//**返回指定文件最后的修改时间 */
48 public final long fileModified(String name) throws IOException {
49 ensureOpen();
50 RAMFile file;
51 synchronized (this) {
52 file = (RAMFile)fileMap.get(name);
53 }
54 if (file==null)
55 throw new FileNotFoundException(name);
56 return file.getLastModified();
57 }
58 /** *//**将指定文件的最后修改时间设置为现在 */
59 public void touchFile(String name) throws IOException {
60 ensureOpen();
61 RAMFile file;
62 synchronized (this) {
63 file = (RAMFile)fileMap.get(name);
64 }
65 if (file==null)
66 throw new FileNotFoundException(name);
67
68 long ts2, ts1 = System.currentTimeMillis();
69 do {
70 try {
71 Thread.sleep(0, 1);
72 } catch (InterruptedException e) {}
73 ts2 = System.currentTimeMillis();
74 } while(ts1 == ts2);
75
76 file.setLastModified(ts2);
77 }
78 /** *//** 返回指定文件的大小*/
79 public final long fileLength(String name) throws IOException {
80 ensureOpen();
81 RAMFile file;
82 synchronized (this) {
83 file = (RAMFile)fileMap.get(name);
84 }
85 if (file==null)
86 throw new FileNotFoundException(name);
87 return file.getLength();
88 }
89
90 /** *//** 返回当前目录中所有的文件大小*/
91 public synchronized final long sizeInBytes() {
92 ensureOpen();
93 return sizeInBytes;
94 }
95 /** *//** 删除指定文件名的文件*/
96 public synchronized void deleteFile(String name) throws IOException {
97 ensureOpen();
98 RAMFile file = (RAMFile)fileMap.get(name);
99 if (file!=null) {
100 fileMap.remove(name);
101 file.directory = null;
102 sizeInBytes -= file.sizeInBytes; // updates to RAMFile.sizeInBytes synchronized on directory
103 } else
104 throw new FileNotFoundException(name);
105 }
106 /** *//**根据制定的名称,创建一个空文件,并且返回操作该文件的输出流。 */
107 public IndexOutput createOutput(String name) throws IOException {
108 ensureOpen();
109 RAMFile file = new RAMFile(this);
110 synchronized (this) {
111 RAMFile existing = (RAMFile)fileMap.get(name);
112 if (existing!=null) {
113 sizeInBytes -= existing.sizeInBytes;
114 existing.directory = null;
115 }
116 fileMap.put(name, file);
117 }
118 return new RAMOutputStream(file);
119 }
120 /** *//** 根据指定的文件名返回一个操作该文件的输入流 */
121 public IndexInput openInput(String name) throws IOException {
122 ensureOpen();
123 RAMFile file;
124 synchronized (this) {
125 file = (RAMFile)fileMap.get(name);
126 }
127 if (file == null)
128 throw new FileNotFoundException(name);
129 return new RAMInputStream(file);
130 }
131
132 /** *//** 关闭并且释放索引占用的内存 */
133 public void close() {
134 isOpen = false;
135 fileMap = null;
136 }
137}
2 public class RAMDirectory extends Directory implements Serializable {
3 private static final long serialVersionUID = 1l;
4 HashMap fileMap = new HashMap(); //首先定了保存文件名以及的Map
5 long sizeInBytes = 0; //文件占用的字节数
6 /** *//** 构造函数。指定LockFactory为该类的一个实例SingleInstanceLockFactory,SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例*/
7 public RAMDirectory() {
8 setLockFactory(new SingleInstanceLockFactory());
9 }
10 /** *//** 定义一个新的RAMDirectory,并且指定其目录,这个做的目的可以将一个文件系统的索引加载到内存中,这个只能使用在该索引能够被全部加在到内存中。这次只是将系统文件的索引拷贝一份到内存中,加载后,系统文件索引发生变化,将不会在该实例中体现。 */
11 public RAMDirectory(Directory dir) throws IOException {
12 this(dir, false);
13 }
14 /** *//** 根据目录,以及参数将该目录中的所有文件复制到内存中,需要复制的文件已经存在,则直接覆盖。closeDir表示是否关闭源目录*/
15 private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
16 this();
17 Directory.copy(dir, this, closeDir);
18 }
19 /** *//**根据提供的文件路径,将该文件路径下的所有的文件复制到内存中,并且创建一个RAMDirectory对象。如果需要复制的对象已经存在,则覆盖原来的文件*/
20 public RAMDirectory(File dir) throws IOException {
21 this(FSDirectory.getDirectory(dir), true);
22 }
23/** *//**根据提供的String路径,将该文件路径下的所有的文件复制到内存中,并且创建一个RAMDirectory对象。如果需要复制的对象已经存在,则覆盖原来的文件*/
24 public RAMDirectory(String dir) throws IOException {
25 this(FSDirectory.getDirectory(dir), true);
26 }
27 /** *//**返回所有该文件该内存索引中的所有文件 */
28 public synchronized final String[] list() {
29 ensureOpen();
30 Set fileNames = fileMap.keySet(); //该文件的所有key
31 String[] result = new String[fileNames.size()];
32 int i = 0;
33 Iterator it = fileNames.iterator();
34 while (it.hasNext())
35 result[i++] = (String)it.next();
36 return result;
37 }
38 /** *//**如果指定文件名的文件在索引中存在,则返回true,否则返回false*/
39 public final boolean fileExists(String name) {
40 ensureOpen();
41 RAMFile file;
42 synchronized (this) {
43 file = (RAMFile)fileMap.get(name);
44 }
45 return file != null;
46 }
47/** *//**返回指定文件最后的修改时间 */
48 public final long fileModified(String name) throws IOException {
49 ensureOpen();
50 RAMFile file;
51 synchronized (this) {
52 file = (RAMFile)fileMap.get(name);
53 }
54 if (file==null)
55 throw new FileNotFoundException(name);
56 return file.getLastModified();
57 }
58 /** *//**将指定文件的最后修改时间设置为现在 */
59 public void touchFile(String name) throws IOException {
60 ensureOpen();
61 RAMFile file;
62 synchronized (this) {
63 file = (RAMFile)fileMap.get(name);
64 }
65 if (file==null)
66 throw new FileNotFoundException(name);
67
68 long ts2, ts1 = System.currentTimeMillis();
69 do {
70 try {
71 Thread.sleep(0, 1);
72 } catch (InterruptedException e) {}
73 ts2 = System.currentTimeMillis();
74 } while(ts1 == ts2);
75
76 file.setLastModified(ts2);
77 }
78 /** *//** 返回指定文件的大小*/
79 public final long fileLength(String name) throws IOException {
80 ensureOpen();
81 RAMFile file;
82 synchronized (this) {
83 file = (RAMFile)fileMap.get(name);
84 }
85 if (file==null)
86 throw new FileNotFoundException(name);
87 return file.getLength();
88 }
89
90 /** *//** 返回当前目录中所有的文件大小*/
91 public synchronized final long sizeInBytes() {
92 ensureOpen();
93 return sizeInBytes;
94 }
95 /** *//** 删除指定文件名的文件*/
96 public synchronized void deleteFile(String name) throws IOException {
97 ensureOpen();
98 RAMFile file = (RAMFile)fileMap.get(name);
99 if (file!=null) {
100 fileMap.remove(name);
101 file.directory = null;
102 sizeInBytes -= file.sizeInBytes; // updates to RAMFile.sizeInBytes synchronized on directory
103 } else
104 throw new FileNotFoundException(name);
105 }
106 /** *//**根据制定的名称,创建一个空文件,并且返回操作该文件的输出流。 */
107 public IndexOutput createOutput(String name) throws IOException {
108 ensureOpen();
109 RAMFile file = new RAMFile(this);
110 synchronized (this) {
111 RAMFile existing = (RAMFile)fileMap.get(name);
112 if (existing!=null) {
113 sizeInBytes -= existing.sizeInBytes;
114 existing.directory = null;
115 }
116 fileMap.put(name, file);
117 }
118 return new RAMOutputStream(file);
119 }
120 /** *//** 根据指定的文件名返回一个操作该文件的输入流 */
121 public IndexInput openInput(String name) throws IOException {
122 ensureOpen();
123 RAMFile file;
124 synchronized (this) {
125 file = (RAMFile)fileMap.get(name);
126 }
127 if (file == null)
128 throw new FileNotFoundException(name);
129 return new RAMInputStream(file);
130 }
131
132 /** *//** 关闭并且释放索引占用的内存 */
133 public void close() {
134 isOpen = false;
135 fileMap = null;
136 }
137}
由于RAMDirectory是抽象类Directory根据内存来实现的,所以他不是永久性存在,一旦内存释放,索引就会消失。不像FSDirectory有一个本地的文件来存储索引。
我们看看RAMDirectory的构造函数,特别是根据本地的目录来创建。将永久保存的文件初始化到内存中。因为内存的操作速度肯定比操作文件要快很倍。这样索引的速度就大大的提供了。
将指定的dir目录拷贝到当前的内存中,即实例化一个RAMDirectory。这里,closeDir是一个很重要的状态变量,指定了拷贝完成后,源目录dir是否关闭。如果实例化一个RAMDirectory完成后就关闭源目录dir,可能会因为处理的时间非常短,而需要再次打开源目录dir,持久化到文件系统目录,开销可能会比直接操作源目录dir要大,这点要权衡。