Java是以小端还是大端来读取整数?
我问,因为我正在从C进程发送一个字节stream到Java。 在C端,32位整数的LSB是第一个字节,MSB是第四个字节。
所以我的问题是在Java端读取从C进程发送的字节时,Java端的endian是什么?
后续的问题,如果在Java端的序列是不一样的发送,我怎么能在它们之间进行转换?
使用networking字节顺序(big endian),这与Java使用的一样。 在C中看到不同的翻译人。
我通过谷歌偶然发现,并得到了我的答案,Java是大端。
通过阅读回应,我想指出,字节确实有一个endian顺序,虽然仁慈,如果你只处理“主stream”微处理器,你不可能遇到过英特尔,摩托罗拉和Zilog所有同意他们的UART芯片的移位方向,并且在他们的CPU中一个字节的MSB将是2 ** 7和LSB将是2 ** 0(我用FORTRAN功率符号来强调这个东西是多大的:)。
20多年前,我用一些航天飞机位串行下行链路数据遇到了这个问题,当时我们用一台Mac电脑取代了一个10K的接口硬件。 有一个关于它很久以前发表的NASA技术简报。 在每个字节从位stream中移入之后,我简单地使用了一个256位元素的查找表,并将位反转(表[0x01] = 0x80等)。
Java中没有无符号整数(全部都是有符号的,而且是Big Endian)。
在C端,每个字节都有一个LSB在起始处在左边,MSB在结尾处。
这听起来像你正在使用LSB作为最低有效位,是吗? LSB通常代表最不重要的字节。 字节序不是基于位的,而是基于字节的。
从无符号字节转换为Java整数:
int i = (int) b & 0xFF;
从byte []中的无符号32位小端转换为Java long(从头开始,未经testing):
long l = (long)b[0] & 0xFF; l += ((long)b[1] & 0xFF) << 8; l += ((long)b[2] & 0xFF) << 16; l += ((long)b[3] & 0xFF) << 24;
没有办法可以影响Java中的任何东西,因为没有(直接非API)的方式将一些字节直接映射到Java中的int。
每个执行此操作或类似操作的API都会相当精确地定义行为,因此您应该查看该API的文档。
我会逐个读取字节,并将它们组合成一个长整型值。 这样你可以控制字节顺序,而且沟通过程是透明的。
如果它适合您使用的协议,请考虑使用DataInputStream,其中的行为非常好定义 。