A variable-length format for positive integers is
defined where the high-order bit of each byte indicates whether more
bytes remain to be read. The low-order seven bits are appended as
increasingly more significant bits in the resulting integer value.
Thus values from zero to 127 may be stored in a single byte, values
from 128 to 16,383 may be stored in two bytes, and so on.
可变格式的整型定义:最高位表示是否还有字节要读取,低七位就是就是具体的有效位,添加到
结果数据中。比如00000001 最高位表示0,那么说明这个数就是一个字节表示,有效位是后面的七位0000001,值为1。10000010 00000001 第一个字节最高位为1,表示后面还有字节,第二位最高位0表示到此为止了,即就是两个字节,那么具体的值注意,是从最后一个字节的七位有效数放在最前面,依次放置,最后是第一个自己的七位有效位,所以这个数表示 0000001 0000010,换算成整数就是130
VInt Encoding Example
|
Value
|
First byte
|
Second byte
|
Third byte
|
|
0
|
00000000
|
|
|
|
1
|
00000001
|
|
|
|
2
|
00000010
|
|
|
|
...
|
|
|
|
|
127
|
01111111
|
|
|
|
128
|
10000000
|
00000001
|
|
|
129
|
10000001
|
00000001
|
|
|
130
|
10000010
|
00000001
|
|
|
...
|
|
|
|
|
16,383
|
11111111
|
01111111
|
|
|
16,384
|
10000000
|
10000000
|
00000001
|
|
16,385
|
10000001
|
10000000
|
00000001
|
|
...
|
|
|
|
Lucene源代码中进行存储和读取是这样的。OutputStream是负责写:
1 /** Writes an int in a variable-length format. Writes between one and
2 * five bytes. Smaller values take fewer bytes. Negative numbers are not
3 * supported.
4 * @see InputStream#readVInt()
5 */
6 public final void writeVInt(int i) throws IOException {
7 while ((i & ~0x7F) != 0) {
8 writeByte((byte)((i & 0x7f) | 0x80));
9 i >>>= 7;
10 }
11 writeByte((byte)i);
12 }
InputStream负责读:
1 /** Reads an int stored in variable-length format. Reads between one and
2 * five bytes. Smaller values take fewer bytes. Negative numbers are not
3 * supported.
4 * @see OutputStream#writeVInt(int)
5 */
6 public final int readVInt() throws IOException {
7 byte b = readByte();
8 int i = b & 0x7F;
9 for (int shift = 7; (b & 0x80) != 0; shift += 7) {
10 b = readByte();
11 i |= (b & 0x7F) << shift;
12 }
13 return i;
14 }
>>>表示无符号右移