频道
bg

Java字节数据处理

coding十一月 02, 20211mins
Java

内存中的数据,我们很少关注到它是如何存储的。但是如果涉及到网络传输,但是数据是如何存储的很关键,因为需求在接受数据时使用存储时的规则来解释,否则很容易产生不一致的。

Java中的数据类型都是有符号的,意味着它需要额外的一个比特位来表示符号,就意味和无符号的数据类型相比,同样的大小的字节,表示的范围大小是不一样的;同样的字节数组,代表的数字也是 不一样的。

数据类型H1

Byte类型H2

byte 数据类型是8位、有符号的,以二进制补码表示的整数。

补码:正数和0的补码就是该数字本身。负数的补码则是将其对应正数按位取反再加1。

例如 -127,首先127的二进制表示为111 1111,取反后为000 0000,再加1为000 0001,最后加上符号为就是1000 0001,而1000 0001本身表示无符号的数为129。

所以Java中byte表示的范围是-128(1000 0001)【1111 1111代表-1】到(0111 1111),但是你依然可以将它解释为0-255。129(1000 0001)解释成byte类型的值为-127(后7为减1取反为111 1111)。反过来如果想知道一个byte数据的无符号表示的话,只需要将第1为也看成数据位,从二进制换算成十禁止即可。

java

byte a = (byte)129;
// -127
byte b = -127;
b & 0xff;
// 129

高低位H1

端序指的是数据的高地位和处理上的先后的关系。比如:高位先处理;低位先处理

一个数据类型如果需要多个字节来存储,那么低位(数学意义上)存储到内存的地位地址,这成为小端字节序(Little Endian);也可以高位存储到内存的低位地址,称为大端字节序(Big Endian)。

X86平台是小端字节序的,也就是说数据从地位往高位存。

如果数据通过网络发送的,发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。 但是这点其实是无所谓的,重点是保存和发送要保持一致。

TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。这里主要是指报文数据在缓存区的存储顺序(可以把缓冲区理解成网络场景下的内存)。

可能影响字节顺序的环节包括

  • 业务数据到字节的转换 这个可能是语言统一处理的,也可能是业务规定的
  • 字节在内存的存储顺序 这个是有系统平台决定的
  • 网络发送顺序 一般是从内存的低地址开始发送

不管如何,核心的思想是要保证接收端和发送端要保持一致。业务上的字节序,可以这么去理解:

不用管网络、内存中的发送、存储方式,看数据的地位存储的是数据的高位还是地位,数字的[0]存的高位,则是大端序

数据处理H1

获取字节的某一位H2

java

// 取位
System.out.println((-128 >> 7) & 0x1 );

字符串和字节数组间的转换H2

使用Netty的ByteBufUtil

评论


新的评论

匹配您的Gravatar头像

Joen Yu

@2022 JoenYu, all rights reserved. Made with love.