Java 范例 - 字節處理


前言

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

字節序

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

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

Big Endian

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

Little Endian

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

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

字節序轉換

由於 Java 使用大端字節序在內存中進行數據存儲,所以進行網絡傳輸時不需要進行字節序轉換。不過除了網絡編程,還是有需要小端字節序的情況,下面就來討論如何進行字節序的轉換。

基本類型字節數

下表給出了 Java 八種基本類型的所占的字節數,可以看到里面六種類型都是多字節的,而這六種在轉換時都是需要處理的。

類型 字節數
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[]) 包裝一個現有的字節數組。

字節緩沖區提供了 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'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM