【问题标题】:Reading 31 bit Integer from Java InputStream从 Java InputStream 读取 31 位整数
【发布时间】:2021-07-02 05:14:51
【问题描述】:

我正在尝试从 java 中的 InputStream 中读取一个 31 位长的整数,但我想不出办法来做到这一点。我从 InputStream 收到四个字节,第一个字节的第一位是保留位,始终未设置(0x0),其余为 31 位长整数。这是我描述的可视化:

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

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

【问题讨论】:

  • 当你说“第一个字节的第一位是一个 reversed byte 它总是 onset (0x0)”时,我认为你的意思是说“第一个字节的第一位是一个保留位,它总是未设置(0x0)”。
  • @Abra 因为“第一个字节的第一位”是R 位所在的位置,所以它是大端。

标签: java inputstream java-io


【解决方案1】:

我正在尝试从 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. 如果未设置“R”位,isolatedBit 将为 0,如果已设置,则为“1”。
  3. 即使设置了这个 R 事物,最后一行也将确保 v 的值未设置该位。因此,该数字将介于 0 和 2^31-1 之间(因此,始终为正数)。

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

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

【讨论】:

  • 我相信当 OP 说“第一个字节的第一位是一个 反转字节,它总是 onset (0x0)”,什么 OP意思是“第一个字节的第一位是一个保留位,它总是未设置(0x0)”
猜你喜欢
  • 1970-01-01
  • 2011-09-03
  • 2010-10-11
  • 2023-04-06
  • 2012-04-30
  • 2012-03-03
  • 2010-12-20
  • 2011-12-14
相关资源
最近更新 更多