csusky

常用链接

统计

最新评论

org.apache.lucene.store.OutputStream

OutputStream
这是一个Abstract类,是Lucene自己的一个文件输出流的基类
BUFFER_SIZE = 1024  缓冲区 大小为 1024bit
bufferStart = 0 文件位置指针
bufferPosition = 0 内存缓冲区指针

 public final void writeByte(byte b) throws IOException {
    if (bufferPosition >= BUFFER_SIZE)
      flush();
    buffer[bufferPosition++] = b;
  }
几乎所有的写入函数都要调用这个函数,如果缓冲区的当前容量已经等于他的最大容量,则将缓冲区中的数据写入文件。

public final void writeBytes(byte[] b, int length) throws IOException
批量写byte进入内存缓冲

public final void writeInt(int i) throws IOException
写入整形数据

public final void writeLong(long i) throws IOException
写入长整型数据,即结合移位运算调用两次writeInt(int i)

另外,最值得注意的是在该类中有两个最特殊的函数
writeVInt(int i) /   writeVLong(long i),
先说
writeVInt(int  i )   {
 while ((i & ~0x7F) != 0) {                               
      writeByte((byte)((i & 0x7f) | 0x80));
      i >>>= 7;
    }
    writeByte((byte)i);
}
~0x7F==~(0111 1111)==(1000 0000)==0x80
((i & ~0x7F) != 0) 这一句判断i是否大于0x80,如果不是则说明该int只有一个字节的有效数据,其他字节都是0,直接转化为Byte写入。
如果大于0x80则
(i & 0x7f) | 0x80
i&0x7f 只对后7位进行处理,|0x80将第8位置1,与前面的7个bit构成一个字节,置1的原因是说明该字节并不是一个完整的整形数,需要与其他的字节合起来才能构成一个整形数字。
这个算法相当于将一个32bit的整形数字按照每7位编码成一个字节进行存储,将按照整形数的大小存储1-5个字节。

writeVLong(long i)方法大致与其相同。

final void writeChars(String s, int start, int length)
将字符串转化成UTF-8编码的格式进行存储。
附:

UNICODE值 UTF-8编码
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx

可见对于在 0x00-0x7F范围内的UNICODE值(最大有效数位:7位),将会编码成单字节的,会大大节约存储空间。
对于在           0x80-0x7FF范围内的UNICODE(最大有效数位:11位),会编码成双字节的。先存储原字节低5位的数位,且将最高位和次高位都置1,再次高位置0(writeByte((byte)(0xC0 | (code >> 6)));)。然后存储后6位的字节,将前两位置10(writeByte((byte)(0x80 | (code & 0x3F)));)
对于其他的UNICODE值则
writeByte((byte)(0xE0 | (code >>> 12)));               4位
 writeByte((byte)(0x80 | ((code >> 6) & 0x3F)));   5位
 writeByte((byte)(0x80 | (code & 0x3F)));            3- 5位

final void writeString(String s) throws IOException
该函数首先用s.length()判断该String总共有多少个字符
然后首先调用writeVInt写入这个字符长度
再调用writeChars(s,s.length())写入字符


在inputStream中的readString()方法则与其相反,首先用readVInt()方法读取字符长度len 然后读取len长度的字符

protected final void flush() throws IOException
该方法调用另外一个方法flushBuffer将缓冲区中的数据输出,然后清空缓冲区;

abstract void flushBuffer(byte[] b, int len) throws IOException
可见flushBuffer方法是abstract的,即需要其子类对该方法进行覆写,以定位该输出流的输出方式。

final long getFilePointer() throws IOException
得到文件指针的位置,即得到输出流已经输出的字节数。

public void seek(long pos) throws IOException
输出缓冲区的内容,然后将文件指针定位到long所指示的文件位置。

abstract long length() throws IOException
返回文件中已有的字节数。需要子类实现。

















posted on 2008-04-16 21:24 晓宇 阅读(208) 评论(0)  编辑  收藏 所属分类: LUCENE


只有注册用户登录后才能发表评论。


网站导航: