从 Java InputStream 读取 31 位整数

问题描述

我正在尝试从 java 中的 InputStream 读取一个 31 位长的整数,但我无法找到解决此问题的方法。我从 InputStream 接收四个字节,第一个字节的第一位是保留位,它始终未设置 (0x0),其余是 31 位长整数。这是我所描述的可视化:

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

如果您能帮我提出解决方案,我将不胜感激。谢谢!

解决方法

我正在尝试从 InputStream 读取一个 31 位长的整数

那是不可能的。

你可以读取的最小大小是一个字节,即 8 位;你能从中读出的所有东西都是 8 的倍数。

并且第一个字节的第一位是一个反向字节,它总是开始(0x0)

这句话没有任何意义。第一个“字节的位”不能是“反转字节”。鉴于位是一维概念,因此没有“反转位”和“开始”这样的东西,如果它有任何意义,则意味着“1”而不是“0”,并且通常不传达位'0x' 语法,十六进制。

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

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

  1. 您需要知道它是“大端”还是“小端”。它将在文档中的某个地方;通常协议是大端的。

  2. 第一部分可以轻松地剥离或隔离,这应该会有所帮助。

假设大端:

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

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

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

鉴于保留位始终未设置,您只需调用 int v = data.readInt(),这是 try 块中唯一需要的内容。如果“保留位”始终为 1 - 您需要 & 0x7FFFFFFF 来摆脱它。