Java 範例 - 字節處理

前言

Java 編程中常會遇到須要進行字節處理的地方,本篇文章就來探討編程中會遇到的字節處理問題。編程

字節序

字節序(endianness)是對於多字節數據來講的,它描述了多字節數據存儲的順序,分爲大端字節序(big endian)和小端字節序(little endian)兩種。數組

大端序即高位字節位於低地址,而小端字節序則與之相反。例如 4 字節的數據 0x01234567,其 大、小端字節序存儲順序以下。網絡

Big Endian編碼

address |0x100|0x101|0x102|0x103|
content |01   |23   |45   |67   |

Little Endiancode

address |0x100|0x101|0x102|0x103|
content |67   |45   |23   |01   |

爲保證數據在不一樣設備進行傳輸時能被正確解析,規定了使用大端字節序做爲網絡字節序orm

字節序轉換

因爲 Java 使用大端字節序在內存中進行數據存儲,因此進行網絡傳輸時不須要進行字節序轉換。不過除了網絡編程,仍是有須要小端字節序的狀況,下面就來討論如何進行字節序的轉換。內存

基本類型字節數

下表給出了 Java 八種基本類型的所佔的字節數,能夠看到裏面六種類型都是多字節的,而這六種在轉換時都是須要處理的。ci

類型 字節數
byte 1
boolean 1
char 2
short 2
int 4
float 4
long 8
double 8

這裏須要強調一點,基本類型的數組形式雖是多字節的,但其字節序只和數組元素有關,而與數組元素的順序無關。例如存在短整形數組 {0x0001, 0x0002} (Java 默認的大端字節序),則其小端字節序是 {0x0100, 0x0200}字符串

字節緩衝區

字節緩衝區(ByteBuffer)經常使用於數據的字節級處理,能夠利用靜態方法 ByteBuffer allocate(int) 來申請一塊固定大小的緩衝區,或者使用 ByteBuffer wrap(byte[]) 包裝一個現有的字節數組。get

字節緩衝區提供了 void order(ByteOrder) 方法來設置該字節緩衝區的字節序,提供了 asTypeBuffer() (其中 Type 爲多字節的基本類型)來將字節緩衝區做爲其餘基本類型緩衝區,以便於插入其餘基本類型,利用這些特性即可實現基本類型的字節序轉換。

基本類型及其數組的字節序轉換

下面例子利用了字節緩衝區來進行整型的字節序轉換,而只需將 asIntBuffer() 改爲相應基本類型的 asTypeBuffer() 方法,就能夠進行其它基本類型的字節序轉換。

int data = 0x01020304;
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);

buf.asIntBuffer().put(data);
// [1, 2, 3, 4]
System.out.println(Arrays.toString(buf.array()));

buf.order(ByteOrder.LITTLE_ENDIAN);
buf.asIntBuffer().put(data);
// [4, 3, 2, 1]
System.out.println(Arrays.toString(buf.array()));

對於基本類型的數組,只需將 data 數據改爲數組便可,以下面給出的例子。

int[] data = new int[]{0x01020304, 0x05060708};
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES * data.length);

buf.asIntBuffer().put(data);
// [1, 2, 3, 4, 5, 6, 7, 8]
System.out.println(Arrays.toString(buf.array()));

buf.order(ByteOrder.LITTLE_ENDIAN);
buf.asIntBuffer().put(data);
// [4, 3, 2, 1, 8, 7, 6, 5]
System.out.println(Arrays.toString(buf.array()));

字符串的字節序轉換

Java 中字符類型使用 Unicode 字符集,因此佔用兩個字節,而字符串只須要將其轉成字符數組便可進行字節序轉換。

char[] data = new String("example").toCharArray();
ByteBuffer buf = ByteBuffer.allocate(Character.BYTES * data.length);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.asCharBuffer().put(data);

字符串編碼與字節數組

編程中一般須要將字符串轉字節數組,而這就涉及到字符串編解碼,但 Java 提供了很便捷的方式來進行轉換,因此無需關心如何字符串編解碼。

byte[] buf = new String("example").getBytes();  // use platform's default charset

注意上面使用了平臺的默認的字符集(可利用 Charset.defaultCharset() 獲取平臺默認字符集)進行解碼,而不是上面提到的 Unicode 字符集,但能夠以下面例子同樣指定字符集。

byte[] buf = new String("example").getBytes("UTF-8");  // use specify charset 'UTF-8'
相關文章
相關標籤/搜索