Java 是否以小端或大端读取整数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/362384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does Java read integers in little endian or big endian?
提问by hhafez
I ask because I am sending a byte stream from a C process to Java. On the C side the 32 bit integer has the LSB is the first byte and MSB is the 4th byte.
我问是因为我正在将字节流从 C 进程发送到 Java。在 C 端,32 位整数的 LSB 是第一个字节,MSB 是第四个字节。
So my question is: On the Java side when we read the byte as it was sent from the C process, what is endianon the Java side?
所以我的问题是:在 Java 端,当我们读取从 C 进程发送的字节时,Java 端的字节序是什么?
A follow-up question: If the endian on the Java side is not the same as the one sent, how can I convert between them?
一个后续问题:如果Java端的字节序与发送的字节序不同,我如何在它们之间进行转换?
采纳答案by Egil
Use the network byte order (big endian), which is the same as Java uses anyway. See man htons for the different translators in C.
使用网络字节顺序(大端),这与 Java 无论如何使用的相同。请参阅 man htons 了解 C 中的不同翻译器。
回答by Jonas Elfstr?m
There are no unsigned integers in Java. All integers are signed and in big endian.
Java 中没有无符号整数。所有整数都是有符号的并且是大端的。
On the C side the each byte has tne LSB at the start is on the left and the MSB at the end.
在 C 端,每个字节的开头都有 tne LSB 在左边,MSB 在结尾。
It sounds like you are using LSB as Least significant bit, are you? LSB usually stands for least significant byte. Endiannessis not bit based but byte based.
听起来您使用 LSB 作为最低有效位,是吗?LSB 通常代表最低有效字节。 字节序不是基于位而是基于字节的。
To convert from unsigned byte to a Java integer:
要将无符号字节转换为 Java 整数:
int i = (int) b & 0xFF;
To convert from unsigned 32-bit little-endian in byte[] to Java long (from the top of my head, not tested):
要将 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;
回答by Wouter Lievens
I would read the bytes one by one, and combine them into a longvalue. That way you control the endianness, and the communication process is transparent.
我会一个一个读取字节,并将它们组合成一个长值。这样您就可以控制字节顺序,并且通信过程是透明的。
回答by Ilja Preu?
If it fits the protocol you use, consider using a DataInputStream, where the behavior is very well defined.
如果它适合您使用的协议,请考虑使用 DataInputStream,其中的行为非常明确。
回答by Joachim Sauer
There's no way this could influence anything in Java, since there's no (direct non-API) way to map some bytes directly into an int in Java.
这不可能影响 Java 中的任何内容,因为没有(直接的非 API)方法可以将某些字节直接映射到 Java 中的 int 中。
Every API that does this or something similar defines the behaviour pretty precisely, so you should look up the documentation of that API.
每个执行此操作或类似操作的 API 都非常精确地定义了行为,因此您应该查找该 API 的文档。
回答by WB Greene
I stumbled here via Google and got my answer that Java is big endian.
我是通过 Google 偶然发现这里的,得到的答案是 Java 是大端。
Reading through the responses I'd like to point out that bytes do indeed have an endian order, although mercifully, if you've only dealt with "mainstream" microprocessors you are unlikely to have ever encountered it as Intel, Motorola, and Zilog all agreed on the shift direction of their UART chips and that MSB of a byte would be 2**7 and LSB would be 2**0 in their CPUs (I used the FORTRAN power notation to emphasize how old this stuff is :) ).
通读这些回复,我想指出字节确实有一个字节序,尽管幸运的是,如果你只处理过“主流”微处理器,你不太可能像英特尔、摩托罗拉和 Zilog 一样遇到它同意他们的 UART 芯片的移位方向,并且在他们的 CPU 中,一个字节的 MSB 将是 2**7,LSB 将是 2**0(我使用 FORTRAN 幂表示法来强调这些东西有多老:))。
I ran into this issue with some Space Shuttle bit serial downlink data 20+ years ago when we replaced a $10K interface hardware with a Mac computer. There is a NASA Tech brief published about it long ago. I simply used a 256 element look up table with the bits reversed (table[0x01]=0x80 etc.) after each byte was shifted in from the bit stream.
20 多年前,当我们用 Mac 计算机替换价值 1 万美元的接口硬件时,我遇到了一些 Space Shuttle 位串行下行链路数据的问题。很久以前就有一篇 NASA 技术简报发表过。在每个字节从位流中移入后,我只是使用了一个 256 元素查找表,其中位反转(表 [0x01]=0x80 等)。
回答by Donald W. Smith
Java is 'Big-endian' as noted above. That means that the MSB of an int is on the left if you examine memory (on an Intel CPU at least). The sign bit is also in the MSB for all Java integer types.
Reading a 4 byte unsigned integer from a binary file stored by a 'Little-endian' system takes a bit of adaptation in Java. DataInputStream's readInt() expects Big-endian format.
Here's an example that reads a four byte unsigned value (as displayed by HexEdit as 01 00 00 00) into an integer with a value of 1:
如上所述,Java 是“大端”。这意味着如果您检查内存(至少在 Intel CPU 上),则 int 的 MSB 在左侧。对于所有 Java 整数类型,符号位也在 MSB 中。
从“小端”系统存储的二进制文件中读取 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;
}
回答by user12482548
java force indeed big endian : https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11
java force确实是大端:https: //docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11