98

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

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

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

4

9 回答 9

67

使用网络字节顺序(大端),这与 Java 使用的相同。请参阅 man htons 以了解 C 中的不同翻译器。

于 2008-12-12T10:36:30.603 回答
54

我通过 Google 偶然发现了这里,并得到了 Java 是big endian的答案。

阅读回复我想指出字节确实有一个字节顺序,虽然幸运的是,如果你只处理过“主流”微处理器,你不太可能遇到过它,因为英特尔、摩托罗拉和 Zilog 都是同意他们的 UART 芯片的移位方向,并且一个字节的 MSB将在他们的 CPU 中2**7,LSB 将2**0在他们的 CPU 中(我使用 FORTRAN 幂符号来强调这些东西有多古老 :))。

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

于 2011-12-08T13:52:50.770 回答
20

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

在 C 端,每个字节的开头都有 tne LSB,左侧是 MSB,结尾是 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;
于 2008-12-12T10:23:06.683 回答
12

这不可能影响 Java 中的任何内容,因为没有(直接的非 API)方法可以将某些字节直接映射到 Java 中的 int。

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

于 2008-12-12T21:37:19.340 回答
3

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

于 2008-12-12T10:27:07.393 回答
2

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

于 2008-12-12T11:06:48.717 回答
2

如上所述,Java 是“大端”。这意味着如果您检查内存(至少在 Intel CPU 上),则 int 的 MSB 位于左侧。对于所有 Java 整数类型,符号位也在 MSB 中。
从“Little-endian”系统存储的二进制文件中读取 4 字节无符号整数需要在 Java 中进行一些调整。DataInputStream 的 readInt() 需要大端格式。
这是一个将四字节无符号值(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;        
 }
于 2019-02-18T07:36:33.427 回答
0

java力确实大端:https ://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11

于 2019-12-04T22:16:25.493 回答
0

恕我直言,没有为 java 定义字节序。字节序是硬件之一,但java是高级别的并且隐藏了硬件,所以你不必担心这一点。

唯一与字节序相关的特性是 java lib 如何将 int 和 long 映射到 byte[] (反之亦然)。它使用 Big-Endian,这是最易读和最自然的:

int i=0xAABBCCDD

映射到

byte[] b={0xAA,0xBB,0xCC,0xDD}
于 2022-01-07T13:47:06.447 回答