一、字节顺序
是指占用内存多于一个字节类型的数据在内存中的存放顺序。
计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。
但是,网络传输、文件储存、人类读写习惯使用大端字节序。
java中一个int型数据占用4个字节,假如有一个16进制的int数,int value =(高字节) 0x01020304 (低字节)
小端字节序(little endian):低字节数据存放在内存低地址
大端字节序(bigendian): 低字节数据存放在高地址处
主机字节序跟CPU有关的,IA架构(Intel、AMD)的CPU中是Little-Endian
所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。
由于JVM会根据底层的操作系统和CPU自动进行字节序的转换,
所以我们使用java进行网络编程,几乎感觉不到字节序的存在。
二、ByteBuffer 示例
public static voidbyteOrder() {int x = 0x01020304;
ByteBuffer bb= ByteBuffer.wrap(new byte[4]);
bb.asIntBuffer().put(x);
System.out.println( bb.order()+ " 内存数据 " +Arrays.toString(bb.array()));
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.asIntBuffer().put(x);
System.out.println( bb.order()+ " 内存数据 " +Arrays.toString(bb.array()));
}
BIG_ENDIAN 内存数据 [1, 2, 3, 4]
LITTLE_ENDIAN 内存数据 [4, 3, 2, 1]
三、Java 与 JavaScript 字节转换
如果通信的双方都是Java,则根本不用考虑字节序的问题了。
Java 的 byte 范围是[-128, 127],
JavaScript 的 byte 范围是[0, 256]
四、int 与 byte Array 转换示例
转换时使用相同的字节序
//生成4个字节的网络字节序,网络传输使用大端字节序,相当于int2ByteArray
byte[] getNetworkBytesOrder(intsourceNumber) {byte[] orderBytes = new byte[4];
orderBytes[3] = (byte) (sourceNumber & 0xFF);
orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);returnorderBytes;
}//还原4个字节的网络字节序, 相当于byteArray2Int
int recoverNetworkBytesOrder(byte[] orderBytes) {int sourceNumber = 0;for (int i = 0; i < 4; i++) {
sourceNumber<<= 8;
sourceNumber|= orderBytes[i] & 0xff;
}returnsourceNumber;
}
五
System.out.println(Arrays.toString(intToByteArray(32)));
System.out.println(Arrays.toString(intToByteArray(145)));
System.out.println(Arrays.toString(intToByteArray(256)));
System.out.println(Arrays.toString(intToByteArray2(32)));
System.out.println(Arrays.toString(intToByteArray2(145)));
System.out.println(Arrays.toString(intToByteArray2(256)));//还原
System.out.println(byteArrayToInt2(intToByteArray2(145)));
System.out.println(byteArrayToInt(intToByteArray2(145)));
输出
[0, 0, 0, 32]
[0, 0, 0, -111]
[0, 0, 1, 0]
[0, 0, 0, 32]
[0, 0, 0, -111]
[0, 0, 1, 0]
145
145
public static byte[] intToByteArray(inti) {byte[] result = new byte[4];
result[0] = (byte)((i >> 24) & 0xFF);
result[1] = (byte)((i >> 16) & 0xFF);
result[2] = (byte)((i >> 8) & 0xFF);
result[3] = (byte)(i & 0xFF);returnresult;
}public static byte[] intToByteArray2(inti) {returnByteBuffer
.allocate(4)//默认大端字节序//.order(ByteOrder.LITTLE_ENDIAN)
.putInt(i)
.array();
}public static int byteArrayToInt2(byte[] byteArray) {int value = 0;for (int i = 0; i < 4; i++) {int shift = (4 - 1 - i) * 8;
value+= (byteArray[i] & 0x000000FF) <
}returnvalue;
}public static int byteArrayToInt(byte[] byteArray){returnByteBuffer.wrap(byteArray)//默认大端字节序//.order(ByteOrder.LITTLE_ENDIAN)
.getInt();
}