1 什么大小端
大小端在计算机业界,Endian表示数据在存储器中的存放顺序。
小端模式:数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
大端模式:数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。这种存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。
如整形十进制数字305419896 ,转化为十六进制表示 0x12345678 。其中每2个十六进制位占8个二进制位(1个十六进制位占4个二进制位)。
2 为何有大小端模式之分
在操作系统中x86和一般OS(如windows、FreeBSD、Linux)使用小端模式。但如Mac OS是大端模式。
在计算机系统是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在Java中除了8bit的byte类型,还有16bit的short类型,32bit的int类型等(要看具体编译器)。另外对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个若将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
应用场景
1 不同端模式的处理器进行数据传递时必须要考虑端模式的不同。
2 在网络上传输数据时,由于数据传输的两端对应不同的硬件平台,采用的存储字节顺序可能不一致。所以在TCP/IP协议规定了在网络上必须采用网络字节顺序,也就是大端模式。对于char型数据只占一个字节,无所谓大端和小端。而对于非char类型数据,必须在数据发送到网络上之前将其转换成大端模式。接收网络数据时按符合接受主机的环境接收。
3 Java中的大小端
存储量大于1字节,非char类型,如int,float等要考虑字节顺序问题了。Java由于虚拟机的关系,屏蔽了大小端问题,需要知道的话可用 ByteOrder.nativeOrder()查询。在操作ByteBuffer中,也可使用ByteBuffer.order()进行设置:
// ByteBuffer中字节存储次序 public class Endians { public static void main(String[] args) { // 创建12个字节的字节缓冲区 ByteBuffer bb = ByteBuffer.wrap(new byte[12]); // 存入字符串 bb.asCharBuffer().put("abdcef"); System.out.println(Arrays.toString(bb.array())); // 反转缓冲区 bb.rewind(); // 设置字节存储次序 bb.order(ByteOrder.BIG_ENDIAN); bb.asCharBuffer().put("abcdef"); System.out.println(Arrays.toString(bb.array())); // 反转缓冲区 bb.rewind(); // 设置字节存储次序 bb.order(ByteOrder.LITTLE_ENDIAN); bb.asCharBuffer().put("abcdef"); System.out.println(Arrays.toString(bb.array())); } }
[0, 97, 0, 98, 0, 100, 0, 99, 0, 101, 0, 102]
[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102]
[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0]
前两句打印说明了,ByteBuffer存储字节次序默认为大端模式。最后一段设置了字节存储次序再输出,可看出存储次序为小端模式。
原贴地址:http://www.cnblogs.com/Leo_wl/p/4881204.html