《斯坦福大学:编程范式》第三节2:大端与小端、最小寻址单位

---------------最小寻址单位----------大端编码和小端编码---java

也叫 大尾存储 和小尾存储。windows

正如以前所说,虽然计算机的存储最小单位是 bit/位。网络

可是 基本数据结构 都是以 byte 做为单位。数据结构

好比 bool, 虽然理论上 咱们能够用 1 bit来表示,tcp

但计算机里,咱们至少要用 1 byte(8 bit)来表示它。编码

 

最小寻址单位是指特定的计算机硬件机构所支持的最小数据访问块大小。spa

内存的最小寻址单位为1个字节(1 Byte)即8个bit。也就是说,你没法单独访问bit的信息或者任意小于1字节的信息。 对应的:内存对齐会加快访问。操作系统

硬盘最小访问单位为4KB(依厂商不一样而有所区别,较早的硬盘该单位比较小),这就是一般所讲的“硬盘按块寻址”,一块既指4KB的数据。对应的:4K对齐会加快访问。code

 

在大尾存储 和小尾存储 中也是。blog

 

BigEndian(大端):低字节在高内存地址 
LittleEndian(小端):低字节在低内存地址

 

好比 一个short s =3 ,两个字节

在小端里:  0000,0011  从低位写起

在大端: 0011,0000    从内存地址高位写起。 (以字节为一个最小单位,而不是以bit)

 

大小端字节序与字符集编码之间的联系就是BOM,即 Byte Order Mark,字节顺序标记。例如能够以utf16编码将数据存储到文件中,在文件头部,会存入BOM,以表示在读取数据的时候是按照大端读取仍是小端读取。FEFF表示大端,FFFE表示小端。而utf-8因为其特殊的变长编码规则,致使它是能够自解释的,因此以utf-8编码存储、传输数据时能够选择不加入BOM,同时这也是推荐的方式。

 

由于utf-8代码单元为1字节,每一个字节高位都有标识,每当读到一个字节时,能够根据其高位进行判断。如上图,若是读到0开头的字节,则此字节单独编码;若是读到1十、11十、11110开头的字节,则接着读取对应个数的字节;若是读到10开头的字节,则继续读取,读到1十、11十、11110开头的字节为止。

由此看来,无需BOM而且能够无视字节序。只是utf-8解码程序稍稍麻烦一些。

而utf-16编码方式的代码单元为2字节,则一个代码单元内的两个字节的前后顺序对读取会产生影响,必须指定字节序,不然只能靠猜。

 

 在网络传输中,tcp协议采用大端字节序,也就是先接收到的字节为数据的高位。

在不一样的操做系统平台中,内存采用的字节序可能不一样,x86和通常的OS(如windows,FreeBSD,Linux)使用的是小端模式。但好比Mac OS是大端模式。在不一样平台之间进行网络传输时,须要进行特殊的转换。

在java中,经过 ByteOrder.nativeOrder() 方法能够判断当前平台采用的时大端字节序仍是小端字节序。

public static ByteOrder nativeOrder() { return Bits.byteOrder(); }
static ByteOrder byteOrder() { if (byteOrder == null) throw new Error("Unknown byte order"); return byteOrder; } static { long a = unsafe.allocateMemory(8); try { unsafe.putLong(a, 0x0102030405060708L); byte b = unsafe.getByte(a); switch (b) { case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break; case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break; default: assert false; byteOrder = null; } } finally { unsafe.freeMemory(a); } }

 

主要实现为static静态方法,首先为long分配了8个字节内存,而后为long分配了值,以后拿出long的第一个字节,若是为数据的高位,那么平台采用的是大端字节序,若是为数据的低位,那么平台采用的时小端字节序。

相关文章
相关标签/搜索