java 主机字节序 网络字节序_主机字节序 与 网络字节序

本文介绍了字节顺序的概念,包括小端字节序和大端字节序,并详细讲解了Java中主机字节序与网络字节序的区别。通过ByteBuffer示例展示了如何在Java中进行字节序转换,同时讨论了Java与JavaScript字节转换的差异。此外,还提供了int到byte Array以及从byte Array恢复int值的转换方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、字节顺序

是指占用内存多于一个字节类型的数据在内存中的存放顺序。

计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。

但是,网络传输、文件储存、人类读写习惯使用大端字节序。

java中一个int型数据占用4个字节,假如有一个16进制的int数,int value =(高字节) 0x01020304 (低字节)

小端字节序(little endian):低字节数据存放在内存低地址

大端字节序(bigendian): 低字节数据存放在高地址处

34d40fd92f65199c7873d294a49fb7ea.png

主机字节序跟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();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值