大小端的基础知识:
小端 ( little-endian):低位字节在前,高位字节在后。大端(Big-Endian),则反之。具体而言,就是为了说清楚,CPU架构中1字(word)的存储顺序。计算机内存中数据自然流动的顺序就是:低位先来,高位紧随其后
JAVA中所有的二进制文件都是按大端存储,这种存储方式也被称为network order。即在所有的平台上,如Mac、 PC、 UNIX等等运行JAVA,都不用考虑大小端的问题。麻烦的是不同语言开发的程序进行数据交换,如笔者最近的项目,二进制文件是由C生成的,通过redis 消息通道以Json格式发过来,而C语言默认是小端模式,就涉及到大小端转换。有些平台(如Mac、IBM 390)内置用的大端模式,其它一些平台内置用的小端模式 (如Intel)。JAVA帮你屏蔽了各平台字节顺序的差异。
32位16进制的 0x45679812在内存中的存储(大小端模式)如下图:
/**
* 将小端bytes数据转化为大端数据
* <p>
* 默认网络传输字节为大端,java 全部为大端(与平台无关)
* 关于 “Little-Endian and Big-Endian”,详情请参考:
*
* @param bytes
* @return 转化后得到的整数
* @Link https://howtodoinjava.com/java/basics/little-endian-and-big-endian-in-java/
* </p>
*/
private int bytesToBigEndian(byte[] bytes) {
int result = 0;
if (bytes == null || bytes.length < 0)
return -1;
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.order(ByteOrder.BIG_ENDIAN);
if (bytes.length == RECORD_BYTES_SIZE) {
result = buffer.getInt();
} else if (bytes.length == PORT_BYTES_SIZE) {
// 端口号:0 ~ 65535; Short: -32768 ~ 32767
short tmp = buffer.getShort();
result = tmp < 0 ? getUnsignedShort(tmp) : tmp;
}
if (result < 0) {
logger.info("Length = " + result + " ; original data:" + bytes);
}
return result;
}