---------------最小尋址單位----------大端編碼和小端編碼---java
也叫 大尾存儲 和小尾存儲。windows
正如以前所說,雖然計算機的存儲最小單位是 bit/位。網絡
可是 基本數據結構 都是以 byte 做爲單位。數據結構
好比 bool, 雖然理論上 咱們能夠用 1 bit來表示,tcp
但計算機裏,咱們至少要用 1 byte(8 bit)來表示它。編碼
最小尋址單位是指特定的計算機硬件機構所支持的最小數據訪問塊大小。spa
內存的最小尋址單位爲1個字節(1 Byte)即8個bit。也就是說,你沒法單獨訪問1 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的第一個字節,若是爲數據的高位,那麼平臺採用的是大端字節序,若是爲數據的低位,那麼平臺採用的時小端字節序。