2011-05-09 82 views
5

什麼是將java.nio.ByteBuffer a轉換爲(新創建的)CharBuffer bchar[] b的最快方法。Fast ByteBuffer to CharBuffer or char []

通過這樣做很重要,即a[i] == b[i]。這意味着,不是a[i]a[i+1]一起構成價值b[j],什麼getChar(i)會做,但值應該是「傳播」。

byte a[] = { 1,2,3, 125,126,127, -128,-127,-126 } // each a byte (which are signed) 
char b[] = { 1,2,3, 125,126,127, 128, 129, 130 } // each a char (which are unsigned) 

注意byte:-128具有相同的(低級8)位作爲char:128。因此,我認爲「最好」的解釋將如我上面所述,因爲這些位是相同的。

之後,我還需要反之亦然翻譯:最有效的方式來獲得char[]java.nio.CharBuffer回到一個java.nio.ByteBuffer

+3

你想用這個字符緩衝區做什麼?如果你輸入一個2字節的字符會發生什麼?翻譯後的字節數組應該如何顯示?根據你的需要,最有效的方法可能是不轉換。 – Ishtar 2011-05-09 12:06:21

+1

換句話說,您正在尋找將ByteBuffer的內容解釋爲使用ISO-8859-1編碼的字符序列? – Anon 2011-05-09 12:34:54

+0

假設是,'char []'緩衝區中沒有大於'0xff'的值來進行反向轉換。任何行爲/崩潰都可以(「未指定」)。 ISO-8859-1?據我所知,有些字節不能被任何代碼頁翻譯(例如'\ 0')?我認爲,如果轉儲8位數據流,許多代碼轉換庫不會很好地處理它。但我不瞭解Java,我會查找它。想象一下,我有圖片/圖像數據。 – towi 2011-05-09 12:49:25

回答

11

所以,你想要的是使用編碼ISO-8859-1進行轉換。

我不主張對效率什麼,但至少這是很短寫:

CharBuffer result = Charset.forName("ISO-8859-1").decode(byteBuffer); 

的另一個方向是:

ByteBuffer result = Charset.forName("ISO-8859-1").encode(charBuffer); 

請衡量這個對其他的解決方案。 (公平地說,在Charset.forName部分不應該包括在內,也應重新做一次,不是爲每個緩衝區。)

從Java 7上也存在StandardCharsets類預實例字符集的情況下,使您可以使用

CharBuffer result = StandardCharsets.ISO_8859_1.decode(byteBuffer); 

ByteBuffer result = StandardCharsets.ISO_8859_1.encode(charBuffer); 

代替。 (這些行與之前的行相同,只是查找起來更容易,不會出現錯誤輸入名稱的風險,也不需要捕捉不可能的異常。)

+1

java.nio.StandardCharsets.ISO_8859_1及其同級提供對字符集的簡單引用,無需查找字符串或拋出異常。 – davenpcj 2013-09-21 21:23:10

+0

謝謝你的提示,我更新了答案。 – 2013-09-23 19:34:49

6

我同意@Ishtar的建議,以避免轉換爲新結構,只根據需要進行轉換。

但是,如果你有一堆ByteBuffer,你可以做。

ByteBuffer bb = ... 
byte[] array = bb.array(); 
char[] chars = new char[bb.remaining()]; 
for (int i = 0; i < chars.length; i++) 
    chars[i] = (char) (array[i + bb.position()] & 0xFF); 
+0

好的,這是通用的,安全的。謝謝。但我希望可能會有API調用? – towi 2011-05-09 12:55:16

+0

您可以確定編碼以您想要的方式工作。您可以嘗試使用「US-ASCII」,但我不知道它適用於所有0 - 255. – 2011-05-09 12:59:14

+1

不,US-ASCII僅適用於0-127,其他字節已映射(使用Java時,不使用CharSet API更好的控制)到''?'',其他字符到'(字節)'?''。使用ISO-8859-1完整覆蓋8位範圍,即做你的循環。 – 2011-05-09 19:28:18

0

除了推遲創建CharBuffer,您可能沒有人能夠得到。 如果使用數據作爲字符的代碼並不嚴格需要CharBuffer或char [],只需執行簡單的即時轉換;使用ByteBuffer.get()(相對或絕對),轉換爲char(注意:正如所指出的那樣,您不得不明確地屏蔽事物;否則值128-255將被符號擴展爲不正確的值0xFF80 - 0xFFFF;不需要7位ASCII碼),並使用它。