问题描述
我正在尝试从 java 中的 InputStream 读取一个 31 位长的整数,但我无法找到解决此问题的方法。我从 InputStream 接收四个字节,第一个字节的第一位是保留位,它始终未设置 (0x0),其余是 31 位长整数。这是我所描述的可视化:
+-+-------------+---------------+-------------------------------+
|R| 31 bit long Integer |
+-+-------------------------------------------------------------+
如果您能帮我提出解决方案,我将不胜感激。谢谢!
解决方法
我正在尝试从 InputStream 读取一个 31 位长的整数
那是不可能的。
你可以读取的最小大小是一个字节,即 8 位;你能从中读出的所有东西都是 8 的倍数。
并且第一个字节的第一位是一个反向字节,它总是开始(0x0)
这句话没有任何意义。第一个“字节的位”不能是“反转字节”。鉴于位是一维概念,因此没有“反转位”和“开始”这样的东西,如果它有任何意义,则意味着“1”而不是“0”,并且通常不传达位'0x' 语法,十六进制。
我的结论是,您一定对 API 感到困惑。
但是,更有用一点:如果您有 4 个字节的数据,其中包含一个 31 位长度的整数,那么:
-
您需要知道它是“大端”还是“小端”。它将在文档中的某个地方;通常协议是大端的。
-
第一部分可以轻松地剥离或隔离,这应该会有所帮助。
假设大端:
try (InputStream raw = socket.getInputStream();
DataInputStream data = new DataInputStream(raw)) {
int v = data.readInt();
boolean isolatedBit = (v >>> 31) != 0;
v = v & 0x7FFFFFFF;
}
-
DataInputStream
有处理业务的readInt()
电话。 -
isolatedBit
如果 'R' 位未设置,则为 0,如果设置为 '1'。 - 即使设置了这个 R 东西,最后一行也将确保
v
的值未设置该位。因此,该数字将介于 0 和 2^31-1 之间(因此,始终为正数)。
注意:在对原始问题进行一些更正后,这要简单得多:
鉴于保留位始终未设置,您只需调用 int v = data.readInt()
,这是 try 块中唯一需要的内容。如果“保留位”始终为 1 - 您会需要 & 0x7FFFFFFF
来摆脱它。