Store
Store
里主要是一些对文件的操作类。其主要目的是抽象出和平台文件系统无关的存储抽象,提供诸如目录服务(增、删文件)、输入流和输出流。
主要的类的结构为:抽象类
Directory
类,
InputStream
类和
OutputStream
类。
其中
FSDirectory
,
RAMDirectory
继承了
Directory
抽象类,
FSInputStream
,
RAMInputStream
继承了
InputStream
抽象类,
FSOutputStream
,
RAMOutputStream
继承了
OutputStream
抽象类。
其中
FS
开头的是以实际的文件系统为基础的,以
RAM
开头的是内存中的虚拟文件系统,虚拟文件的类为:
RAMFile
,包含的内容为:
Vector buffers = new Vector();
long length;
long lastModified = System.currentTimeMillis();
RAMFile
中采用数组来表示文件的存储空间。在此的基础上,完成各项操作的实现,就形成了基于内存的虚拟文件系统。
下面具体分析这个内存的虚拟文件系统。
RAMDirectory
类中:
files
信息存在一个
Hashtable
里
Hashtable files = new Hashtable();
创造文件的函数为
public final OutputStream createFile(String name)
{
RAMFile file = new RAMFile();
files.put(name, file);
return new RAMOutputStream(file);
}
即将
name
和
RAMFile
存到一个
Hashtable
中。
打开内存文件的方式为:
public final InputStream openFile(String name)
{
RAMFile file = (RAMFile)files.get(name);
return new RAMInputStream(file);
}
其实就是用一个
Hashtable
来在内存中形成一个文件系统。
再来看看
RAMInputStream
,继承了
InputStream
类的方法,并重写了
readInternal
和
seekInternal
方法。
构造函数
public RAMInputStream(RAMFile f)
{
file = f;
length = file.length;
}
很容易理解。
这里大量用到了抽象类
InputStream
的方法,先从
Lucene
自定义的数据类型看,
Lucene
定义一个
Buffer_Size
的长度为
1024
,并定义一
bufferPosition
指向其在缓冲区的位置。以下是
4
种数据类型基本的。
总之一个无论是
InputStream
还是
OutputStream
其缓冲区都是
1024
字节。存在一个
byte
类型的数组中,我们知道通过数组下标定位是几乎不需要时间的,所以速度上没有问题肯定操作定位很快。主要由硬盘的寻道时间所决定的。在内存中存取速度也是比较快的,省去了读取文件的时间,所以加载常用的信息在内存中是必要的,
光字典就存储了至少
256M
在内存中也充分说明了这一点。内存中的文件系统就看到这。
Lucene
这个也充分考虑了线程的安全性,从用
Java
的
api
可以看出,他用
Hashtable
而不用
HashMap
,用
Vector
而不用
ArrayList
,其还有个
Lock
的抽象类用于控制文件的读写。
下面来看看操作文件的读写类
FSDirectory
,
FSInputStream
和
FSOutputStream
。
FSDirectory
类主要是读取文件夹,其文件信息存在一
Hashtable
里面,存贮的形式为(
File
,
FSDirectory
)
create()
函数为:
private synchronized void create() throws IOException
{
if (!directory.exists())
if (!directory.mkdirs())
throw new IOException(”Cannot create directory: ” + directory);
String[] files = directory.list(); // clear old files
for (int i = 0; i < files.length; i++) {
File file = new File(directory, files);
if (!file.delete())
throw new IOException(”Cannot delete ” + files);
}
读取文件夹的内容直接通过
Hashtable
读取,
public static FSDirectory getDirectory(File file, boolean create)
throws IOException {
file = new File(file.getCanonicalPath());
FSDirectory dir;
synchronized (DIRECTORIES) {
dir = (FSDirectory)DIRECTORIES.get(file); //
先从
HashTable
里读取
if (dir == null) { //
如果不存在
dir = new FSDirectory(file, create);
DIRECTORIES.put(file, dir);
} else if (create) {
dir.create();
}
}
return dir;
}
这个类主要是对
File
类进行操作,主要操作文件夹的创建和读取。
FSInputStream
类解析:通过私有内部类实现文件的随机读取,用到
Java
的
IO
类中的
RandomAccessFile
类
内部类为:
private class Descriptor extends RandomAccessFile
{
//private String name;
public long position;
public Descriptor(File file, String mode) throws IOException //mode
为文件的读写模式
{
super(file, mode);
//name = file.toString();
//debug_printInfo(”OPEN”);
}
Descriptor file = null;//
内部类的使用,
public FSInputStream(File path) throws IOException { //
读取一个文件。
file = new Descriptor(path, “r”);
length = file.length();
}
/**
具体的读入方法
*/
protected final void readInternal(byte[] b, int offset, int len)
throws IOException {
synchronized (file)
{
long position = getFilePointer(); //
取得读的内容所在文件的位置
if (position != file.position) {
file.seek(position); //
定位到位置
file.position = position;
}
int total = 0;
do {
int i = file.read(b, offset+total, len-total); //
读取数据存到
byte
类型的数组
b
中
if (i == -1)
throw new IOException(”read past EOF”); //
文件读完
file.position += i;
total += i;
} while (total < len);
}
}
FSOutputStream
解析:
RandomAccessFile file = null;
然后读写打开文件。
public final void seek(long pos) throws IOException {
super.seek(pos);
file.seek(pos);
} //
寻位置
public final void flushBuffer(byte[] b, int size) throws IOException {
file.write(b, 0, size);
} //
在文件里写数据。
protected final void finalize() throws IOException
{
file.close(); // gc
时关闭文件。
}
还没有评论,来说两句吧...