org.apache.lucene.store.OutputStream
OutputStream這是一個(gè)Abstract類(lèi),是Lucene自己的一個(gè)文件輸出流的基類(lèi)
BUFFER_SIZE = 1024 緩沖區(qū) 大小為 1024bit
bufferStart = 0 文件位置指針
bufferPosition = 0 內(nèi)存緩沖區(qū)指針
public final void writeByte(byte b) throws IOException {
if (bufferPosition >= BUFFER_SIZE)
flush();
buffer[bufferPosition++] = b;
}
幾乎所有的寫(xiě)入函數(shù)都要調(diào)用這個(gè)函數(shù),如果緩沖區(qū)的當(dāng)前容量已經(jīng)等于他的最大容量,則將緩沖區(qū)中的數(shù)據(jù)寫(xiě)入文件。
public final void writeBytes(byte[] b, int length) throws IOException
批量寫(xiě)byte進(jìn)入內(nèi)存緩沖
public final void writeInt(int i) throws IOException
寫(xiě)入整形數(shù)據(jù)
public final void writeLong(long i) throws IOException
寫(xiě)入長(zhǎng)整型數(shù)據(jù),即結(jié)合移位運(yùn)算調(diào)用兩次writeInt(int i)
另外,最值得注意的是在該類(lèi)中有兩個(gè)最特殊的函數(shù)
writeVInt(int i) / writeVLong(long i),
先說(shuō)
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,如果不是則說(shuō)明該int只有一個(gè)字節(jié)的有效數(shù)據(jù),其他字節(jié)都是0,直接轉(zhuǎn)化為Byte寫(xiě)入。
如果大于0x80則
(i & 0x7f) | 0x80
i&0x7f 只對(duì)后7位進(jìn)行處理,|0x80將第8位置1,與前面的7個(gè)bit構(gòu)成一個(gè)字節(jié),置1的原因是說(shuō)明該字節(jié)并不是一個(gè)完整的整形數(shù),需要與其他的字節(jié)合起來(lái)才能構(gòu)成一個(gè)整形數(shù)字。
這個(gè)算法相當(dāng)于將一個(gè)32bit的整形數(shù)字按照每7位編碼成一個(gè)字節(jié)進(jìn)行存儲(chǔ),將按照整形數(shù)的大小存儲(chǔ)1-5個(gè)字節(jié)。
writeVLong(long i)方法大致與其相同。
final void writeChars(String s, int start, int length)
將字符串轉(zhuǎn)化成UTF-8編碼的格式進(jìn)行存儲(chǔ)。
附:
UNICODE值 UTF-8編碼
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
可見(jiàn)對(duì)于在 0x00-0x7F范圍內(nèi)的UNICODE值(最大有效數(shù)位:7位),將會(huì)編碼成單字節(jié)的,會(huì)大大節(jié)約存儲(chǔ)空間。
對(duì)于在 0x80-0x7FF范圍內(nèi)的UNICODE(最大有效數(shù)位:11位),會(huì)編碼成雙字節(jié)的。先存儲(chǔ)原字節(jié)低5位的數(shù)位,且將最高位和次高位都置1,再次高位置0(writeByte((byte)(0xC0 | (code >> 6)));)。然后存儲(chǔ)后6位的字節(jié),將前兩位置10(writeByte((byte)(0x80 | (code & 0x3F)));)
對(duì)于其他的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
該函數(shù)首先用s.length()判斷該String總共有多少個(gè)字符
然后首先調(diào)用writeVInt寫(xiě)入這個(gè)字符長(zhǎng)度
再調(diào)用writeChars(s,s.length())寫(xiě)入字符
在inputStream中的readString()方法則與其相反,首先用readVInt()方法讀取字符長(zhǎng)度len 然后讀取len長(zhǎng)度的字符
protected final void flush() throws IOException
該方法調(diào)用另外一個(gè)方法flushBuffer將緩沖區(qū)中的數(shù)據(jù)輸出,然后清空緩沖區(qū);
abstract void flushBuffer(byte[] b, int len) throws IOException
可見(jiàn)flushBuffer方法是abstract的,即需要其子類(lèi)對(duì)該方法進(jìn)行覆寫(xiě),以定位該輸出流的輸出方式。
final long getFilePointer() throws IOException
得到文件指針的位置,即得到輸出流已經(jīng)輸出的字節(jié)數(shù)。
public void seek(long pos) throws IOException
輸出緩沖區(qū)的內(nèi)容,然后將文件指針定位到long所指示的文件位置。
abstract long length() throws IOException
返回文件中已有的字節(jié)數(shù)。需要子類(lèi)實(shí)現(xiàn)。
posted on 2008-04-16 21:24 曉宇 閱讀(220) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): LUCENE