我正在用 Java 记录一些代码。目标是阅读并处理OSRM文件 http://project-osrm.org/这是一个包含十六进制代码的文件。
流程如下:读入某个字节到aByteBuffer
用一个FileChannel
。缓冲区填满后,将每个字节转换为有符号整数。这是使用按位完成的&
运算符和有符号左移运算符<<
,看起来像这样:
return (0x000000ff & (bb.get() << 0)) |
(0x0000ff00 & (bb.get() << 8)) |
(0x00ff0000 & (bb.get() << 16)) |
(0xff000000 & (bb.get() << 24));
Where bb
当然是ByteBuffer
.
我完全不知道这段代码是如何以及为什么工作的,我用谷歌搜索了一下,我发现的最接近的是以下堆栈溢出问题:将 Java 方法转换为 C#:使用位移运算符将字节转换为整数 https://stackoverflow.com/questions/6920993/converting-java-method-to-c-converting-bytes-to-integers-with-bit-shift-operat.
尽管如此,我还是不知道,我想知道是否有人可以帮助我找出这个代码片段。
这从底层字节缓冲区读取四个字节并将它们拼接在一起形成一个int
像这样的值:
11111111 (first byte read)
22222222 (second byte read)
33333333 (third byte read)
44444444 (fourth byte read)
为了实现这一点,对所有子结果执行按位或运算,其中每个子结果准备上图中的一行。例如,第三行准备为
(0x00ff0000 & (bb.get() << 16))
它执行以下操作:
-
读取字节:
xxxxxxxx
-
扩大byte
进入一个int
:
000000000000000000000000xxxxxxxx
-
将位左移 16 个槽:
00000000xxxxxxxx0000000000000000
-
最后,将其推入 AND 掩码,该掩码仅允许x
位通过。这是需要的,因为byte
已签名,因此转换为int
实际上可能会导致以下结果:
111111111111111111111111xxxxxxxx
如果执行常量 AND 掩码,代码可能会更简单before转移:
(bb.get() & 0xFF) << 16
这实际上是 Java 在这些位操作中的标准习惯用法。
虽然不是您所问问题的答案,但使用提供的 API 肯定是首选(getInt
方法)。您的字节顺序是小尾数,所以您只需要设置它:
bb.order(ByteOrder.LITTLE_ENDIAN);
作为参考,这是 JDK 对相同代码的实现:
static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
return (((b3 ) << 24) |
((b2 & 0xff) << 16) |
((b1 & 0xff) << 8) |
((b0 & 0xff) ));
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)