2010-09-22 95 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不会对整数参数范围进行任何验证。