大端小端
1 前言
在做项目时,需要将报文发送给硬件端,报文打包我都是用的大端写入Bytebuf(使用的netty),老大审查代码时,说我写错了,说硬件那边要求是小端传输。不过改成小端写入也容易,重要的是牢记这个知识点。于是趁这个机会复习一下大端和小端。
2 概念
大端(Big-Endian)和小端(Little-Endian)的定义如下:
小端(Little-Endian)数据的低位字节位存放在内存的低地址端,高位字节存放在内存的高地址端。
大端(Big-Endian) 数据的高位字节位存放在内存的低地址端,低位字节存放在内存的高地址端。
2.1 什么是低地址、低地址
地址编号小的是低地址,地址编号大的是高地址
2.2 什么是低位字节、高位字节
那16进制的数字0x12345678来说,它有4个字节(一个字节八位,而两个16进制的数字占位,一个字节能表示的最大数字位0xFF)
低地址 <=============== 高地址
高位字节 <=============== 低位字节
0x12 | 0x34 | 0x56 | 0x78
在大端模式下的内存存储布局为
低地址 <=============== 高地址
高位字节 <=============== 低位字节
0x12 | 0x34 | 0x56 | 0x78
在小端模式下的内存存储布局为
低地址 <=============== 高地址
高位字节 <=============== 低位字节
0x78 | 0x56 | 0x34 | 0x12
3. 举例
3.1 代码
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;
public class TestEndian {
public static void main(String[] args) {
ByteBuf buffer = Unpooled.buffer();
// 大端写入
buffer.writeInt(0x12345678);
log(buffer);
ByteBuf buffer2 = Unpooled.buffer();
// 小端写入
buffer2.writeIntLE(0x12345678);
log(buffer2);
}
/**
* 显示数据在ByteBuf中的存储接口1
* @param buffer ByteBuf
*/
private static void log(ByteBuf buffer){
int length=buffer.readableBytes();
int rows=length/16+(length%15==0?0:1)+4;
StringBuilder buf=new StringBuilder(rows*80*2)
.append("read index:").append(buffer.readerIndex())
.append(" write index:").append(buffer.writerIndex())
.append(" capacity:").append(buffer.capacity())
.append(NEWLINE);
appendPrettyHexDump(buf,buffer);
System.out.println(buf.toString());
}
}
3.2 控制台结果
read index:0 write index:4 capacity:256
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 12 34 56 78 |.4Vx |
+--------+-------------------------------------------------+----------------+
read index:0 write index:4 capacity:256
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 78 56 34 12 |xV4. |
+--------+-------------------------------------------------+----------------+
控制台中,0,1,2,3,4,...,f
,代表从低地址到高地址,第二行可以看到:
- 大端写入时,高位字节位存放在内存的低地址端,低位字节存放在内存的高地址端;
- 小端写入时,低位字节位存放在内存的低地址端,高位字节存放在内存的高地址端。