2010-09-22 32 views
2

我從一個插座一個字符數組:Java char包含值> 255?

char[] cbuf = new char[3]; 
inputStream.read(cbuf, 0, 3); // read 3 chars in buffer "cbuf", offset = 0 

後來,當我打印:

System.out.println("r:"+(int)cbuf[0]+" g:"+(int)cbuf[1]+" b:"+(int)cbuf[2]); 

我會在某個時刻:

... 
r:82 g:232 b:250 
r:82 g:232 b:250 
r:66 g:233 b:8224 

的值方式超過,一個char如何包含這個值???

謝謝

+0

問題是您正在通過'Reader'而不是'InputStream'讀取數據。一個閱讀器使用一種編碼將字節轉換成字符,在你的情況下它可能是windows-1252。請參閱下面的答案。 – 2010-09-22 00:56:04

+2

我假設你來自C的背景,其中sizeof(char)== sizeof(字節),但即使在C我建議你使用無符號字節作爲r/g/b的值不是字符。 – 2010-09-22 17:59:57

回答

8

char Java中的基元,16位寬,以適應標準ASCII範圍以外的字符,使用Unicode

它看起來像你試圖存儲RGB值在char[3]。我可以建議byte[3]還是java.awt.Color

Color c = new Color(255, 255, 240); 
+1

你是不是指UTF-16? – sje397 2010-09-22 00:22:13

+0

@ sje397:不,我的意思是[修改過的UTF-8和CESU-8](http://en.wikipedia.org/wiki/UTF-8#UTF-8_derivations)。 – 2010-09-22 00:26:20

+2

@Michael Petrotta:不,你的意思是UTF-16。確實,Java也使用修改過的UTF-8,但不適用於字符類型:它根本不可能,因爲對於任何字符> = U + 0800,這需要超過16位。 Java 1.4和更早版本使用UCS-2,Java 1.5切換到UTF-16。 – 2010-09-22 01:00:13

5

char type in Java是16位。

如果您正在查找8位數據類型,請考慮使用byte

+3

它包含Unicode代碼點。 – Thilo 2010-09-22 00:11:02

+1

如果您使用BMP以外的字符,則不適用。 'char'包含的是UTF-16代碼單元。 – dan04 2010-09-22 04:35:45

1

Java使用UTF(非ASCII)存儲字符,UTF是16位長,因此它可以包含高達65.535的值。

+3

並非完全如此。 UTF-16是16位'長'。 UTF-8是8位'長'。雖然這是靈活使用「long」這個詞,因爲每個代碼點都可以有更長的序列。 – sje397 2010-09-22 00:20:40

+0

所以我猜Java使用UTF-16,是嗎? – 2010-09-22 07:05:07

+0

JLS 3.1:「... Java編程語言使用UTF-16編碼表示16位代碼單元序列中的文本...」http://java.sun.com/docs/books/jls/ third_edition/html/lexical.html#248597 – 2010-09-22 12:50:04

7

上有InputStream沒有read(char[], int, int)方法。您必須在Reader子類(例如InputStreamReader)上致電。 InputStreamReader使用平臺默認字符編碼自動將字節轉換爲字符,在您的情況下它看起來像是windows-1252

您收到的字符8224是Unicode字符U+2020 Dagger '†'。這可能是使用windows-1252字符編碼從字節0x86(134)轉換而來的。

如果您正在閱讀包含非文本內容的文件,則需要確保您沒有閱讀Reader的子類,而是使用InputStream的子類代替。或者,您可以使用InputStreamReader並指定一個字符編碼,如ISO-8859-1,它會將每個字節映射到具有相同數值的字符。

+1

澄清:找到創建變量「inputStream」[sic];很可能是使用socket.getInputStream()創建的。刪除包裝的InputStreamReader並確保使用原始InputStream。改爲讀入一個字節[]。確保協議實際上按照您的想法發送3個字節;最後,考慮使用Color。 – KarlP 2010-09-22 15:05:12

+0

感謝+1。 (我不知道字符是16位,所以我接受了另一個答案) – 2010-09-22 15:15:21

2

正如人們已經指出的那樣,您想要讀取字節而不是字符(字符是Java中的16位),並確保您實際使用的是InputStream而不是Reader

我也想指出一些與你的問題沒有直接關係的東西:當調用InputStream.read(byte[])InputStream.read(byte[], int, int)來讀取幾個字節時,不要假設所有請求的字節在返回時都被讀取。撥打read可能會返回一些字節可用。您應該始終檢查返回值以查明實際讀取的字節數。

這同樣適用於方法Reader

0

Chars在Java中未簽名16位整數。儘管在技術上,如果您從不可信字節碼接收值,您必須準備處理任意32位值,因爲JVM不會對整數參數範圍進行任何驗證。