endianness - Java是用小端还是大端读取整数?

我问,因为我正在从C进程向Java发送字节流。 在C端,32位整数的LSB是第一个字节,MSB是第4个字节。

所以我的问题是:在Java端,当我们读取从C进程发送的字节时,Java端的endian是什么?

一个后续问题:如果Java端的endian与发送的端不一样,我怎样才能在它们之间进行转换?

hhafez asked 2019-08-25T06:03:13Z

7个解决方案

60 votes

使用网络字节顺序(big endian),这与Java使用的相同。 请参阅C中的不同翻译人员。

Egil answered 2019-08-25T06:03:25Z

42 votes

我在这里偶然发现了谷歌并得到了我的答案,即Java是大端。

通过阅读回答,我想指出字节确实有一个字节顺序,尽管如果你只是处理了#34;主流" 你不太可能遇到它的微处理器,因为英特尔,摩托罗拉和Zilog都同意他们的UART芯片的移位方向,并且一个字节的MSB为2 ** 7,而其CPU的LSB为2 ** 0( 我使用FORTRAN幂表示法来强调这个东西多大了:))。

20多年前,当我们用Mac计算机替换了价值10美元的接口硬件时,我遇到了一些航天飞机位串行下行链路数据。 很久以前就有一篇关于它的NASA技术简报。 在每个字节从位流中移入后,我只使用256元素查找表,其中位反转(表[0x01] = 0x80等)。

WB Greene answered 2019-08-25T06:04:07Z

18 votes

Java中没有无符号整数。 所有整数都是签名的并且是大端的。

在C侧,每个字节的开头的LSB在左边,MSB在最后。

听起来你使用LSB作为最不重要的一点,是吗? LSB通常代表最低有效字节。字节顺序不是基于位的,而是基于字节的。

要从无符号字节转换为Java整数:

int i = (int) b & 0xFF;

要从byte []中的无符号32位little-endian转换为Java long(从头顶开始,未经测试):

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
Jonas Elfström answered 2019-08-25T06:05:00Z
11 votes

这无法影响Java中的任何东西,因为没有(直接的非API)方式将一些字节直接映射到Java中的int。

执行此操作或类似操作的每个API都非常精确地定义了行为,因此您应该查找该API的文档。

Joachim Sauer answered 2019-08-25T06:05:32Z

3 votes

我会逐个读取字节,并将它们组合成一个long值。 这样您就可以控制字节顺序,并且通信过程是透明的。

Wouter Lievens answered 2019-08-25T06:05:57Z

3 votes

如果它符合您使用的协议,请考虑使用DataInputStream,其中行为定义非常明确。

Ilja Preuß answered 2019-08-25T06:06:22Z

0 votes

Java是Big-endian&#39; 如上所述。 这意味着如果检查内存(至少在Intel CPU上),则int的MSB在左侧。 对于所有Java整数类型,符号位也在MSB中。

从由Little-endian&#39;存储的二进制文件中读取4字节无符号整数。 系统在Java中需要一些改编。 DataInputStream的readInt()需要Big-endian格式。

这是一个将四字节无符号值(由HexEdit显示为01 00 00 00)读取为值为1的整数的示例:

// Declare an array of 4 shorts to hold the four unsigned bytes
short[] tempShort = new short[4];
for (int b = 0; b < 4; b++) {
tempShort[b] = (short)dIStream.readUnsignedByte();
}
int curVal = convToInt(tempShort);
// Pass an array of four shorts which convert from LSB first
public int convToInt(short[] sb)
{
int answer = sb[0];
answer += sb[1] << 8;
answer += sb[2] << 16;
answer += sb[3] << 24;
return answer;
}
Donald W. Smith answered 2019-08-25T06:07:02Z