我看起来有点高于Netflix Hollow库代码(https://github.com/Netflix/hollow),我发现这个功能我找不到任何意义(警告:我对Java不太了解)。 从理论上讲,该函数从InputStream中返回一个可变长度的整数。
/**
* Read a variable length integer from the supplied InputStream
*/
public static int readVInt(InputStream in) throws IOException {
byte b = (byte)in.read();
if(b == (byte) 0x80)
throw new RuntimeException("Attempting to read null value as int");
int value = b & 0x7F;
while ((b & 0x80) != 0) {
b = (byte)in.read();
value <<= 7;
value |= (b & 0x7F);
}
return value;
}
我评论我的怀疑:
1) Int值= b&amp; 0x7F :结果总是b,对吗?有什么意义?
2) while((b&amp; 0x80)!= 0): b&amp;的结果0x80 (如果b是整数位,即从0到9的十进制编码,十进制为48-57)始终为0.因此,永远不会进入循环...
答案 0 :(得分:2)
老实说,在Java中找到这样的低级实现是很奇怪的(IMHO);这种逻辑在C程序和其他接近金属的程序中更常见。语言。但我认为向数百万用户提供有效的流媒体并不是免费的:)
b
是byte
,不是整数。它被解释为8位
0x80
是10000000
,除了高阶(&#34;第一个&#34;)之外,所有位都设置为零的掩码。
0x7F
是01111111
,一个掩码,除第一个之外,所有位都设置为1。 0x80
的倒数
value
是我们想要读取的整数值。这是一个int
,在Java中是4个字节。最初是00000000000000000000000000000000
。
代码逐个读取字节序列。它使用第一位作为终止标记(0表示&#34;最后一个字节&#34;),并将其他7位连接到value
。应用掩码来评估这些位。因此b & 0x80
用于检查第一位是否设置,而b & 0x7F
用于将第一位设置为零并保留所有其他位的值。
示例:
1011101111000110100100111
。 0001011 1011110 0011010 0100111
并使每组成为1个前导的8位字节,除了最后一个将被标记为0前导的字节:10001011 11011110 10011010 00100111
< / LI>
b = 10001011
。由于这不是0x80
(10000000
),我们知道这将是一个有效的非空整数。b & 0x7f
为00001011
)并将value
设置为该位。现在value
是00000000000000000000000000001011
b & 0x80
不为0,因此我们进入循环以读取更多字节。b = 11011110
。丢弃第一位(b & 0x7f
)并将其他7位置于value
内。但是value
已经设置了一些位,所以我们必须将它们移位以为7位以上腾出空间:value <<= 7
。现在value
是00000000000000000000010110000000
。通过使用按位OR运算符value |= (b & 0x7F)
,我们将最低的7位设置为正确的值。现在value
是00000000000000000000010111011110
。 value
是00000000000000101110111100011010
。 00100111
。现在value
是00000001011101111000110100100111
。这是我们打算发送的正确值。 无论如何,我希望这能帮到你。
答案 1 :(得分:0)
重点是:他们可能正在使用他们自己的&#34;确定如何使用流写入和读取值的协议。
在该协议中,值0x80具有特殊含义:&#34;值结束&#34;。
意义:&#34;作家&#34;部分写入一个字节序列,然后输入一个0x80表示不再跟随字节。然后:
while ((b & 0x80) != 0) {
0x8时,评估为 false ?被读了。含义:如果设置了第一位,则&#34;消息结束&#34;。
换句话说:当你想从那个流中读取一个int时;你得到的第一个字节是0x80 - 然后:&#34;你的&#34;没有值;因此例外。
然后你只是逐字节读;然后将这些字节移到结果int值中 - 直到0x80&#34;结束值&#34;标记字节进来。