从 Java InputStream 读取 31 位整数

Reading 31 bit Integer from Java InputStream

我正在尝试从 java 中的 InputStream 中读取一个 31 位长的整数,但我想不出这样做的方法。我从 InputStream 接收到四个字节,第一个字节的第一位是一个保留位,它总是未设置 (0x0),其余的是 31 位长 integer.Here 是我所描述内容的可视化:

+-+-------------+---------------+-------------------------------+
|R|                     31 bit long Integer                     |
+-+-------------------------------------------------------------+

如果你能帮我想出一个解决方案,我将不胜感激。谢谢!

I'm trying to read a 31 bit long Integer from an InputStream

那是不可能的。

你能读取的东西的最小大小是一个字节,也就是8位;你能从中读到的所有东西都是 8 的倍数。

and the first bit of the first byte is a reversed byte which is always onset (0x0)

这句话没有任何意义。第一个 'bit of a byte' 不能是 'reversed byte'。鉴于位是一个一维的概念,所以不存在 'reversed bit' 和 'onset' 之类的东西,如果它有任何意义,则意味着'1'而不是'0',并且位不是以十六进制的“0x”语法传达的规则。

我的结论是您一定对 API 感到困惑。

但是,要更有帮助:如果您有 4 个字节的数据,其中包含一个 31 位长度的整数,那么:

  1. 你需要知道它是'big endian'还是'little endian'。它会在文档中的某个地方;通常协议是大端。

  2. 第一位可以简单地剥离或隔离,这应该有所帮助。

假设大端:

try (InputStream raw = socket.getInputStream();
     DataInputStream data = new DataInputStream(raw)) {

  int v = data.readInt();
  boolean isolatedBit = (v >>> 31) != 0;
  v = v & 0x7FFFFFFF;
}
  1. DataInputStreamreadInt() 电话处理业务。
  2. 如果未设置 'R' 位,
  3. isolatedBit 将为 0,如果已设置,则为 '1'。
  4. 即使这个 R 东西被设置了,最后一行将确保 v 的值没有设置那个位。因此,数字将介于 0 和 2^31-1 之间(因此,始终为正数)。

注意:在对原始问题进行了一些更正之后,这就简单多了:

鉴于保留位始终未设置,您只需调用 int v = data.readInt(),这是 try 块中唯一需要的东西。如果 'reserved bit' 一直是 1 - 你 需要 & 0x7FFFFFFF 来摆脱它。