在一个简单的服务器客户端应用程序中,我正在以这种方式读取数据:
if((value=in.read())!=-1) {
if(protocol.newChar((char)value, input)) {
//Consider curent buffer data a message
protocol.receiveMessage(input.toString());
//Clear some buffer
input.setLength(0);
}
}
现在,在java文档中,他们说方法read
将单个字符“读取为0到65535(0x00-0xffff)范围内的整数,如果流的末尾有,则为-1已到达“。
将字符读作整数除外,我仍然对这个函数给出的结果感到困惑 - 我将整数发送为4个字节(我把它放在字节数组中并发送它)。
在接收方,我在控制台中看到了这一点:
Received character: [0]
Received character: [0]
Received character: [0]
Received character: [8]
由此代码生成,其中current
是char
返回的in.read()
:
Log.debug("Received character: "+current+" ["+(int)current+"]");
显然我很困惑发生的事情。发送函数是否将字节转换回字符?
在调试过程中,我发现了一件有趣的事情 - netbeans控制台中的\0
可以与其他文本一起复制。在粘贴期间,仅粘贴第一个\0
之前的数据。 (Windows 7)
答案 0 :(得分:4)
Reader
只读char
,而不是byte
。它通常通过读取字节并通过您手动指定的字符集或通过系统默认值将它们转换为char
来实现(最终,取决于读者,其委托等)。 InputStreamReader
通常会发生这种情况。从那个班级' Javadoc中:
每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。为了有效地将字节转换为字符,可以从基础流中提取比满足当前读取操作所需的更多字节。
所以答案是真的,"它的实现已定义,"但是它将至少,因为形成一个char需要很多字节。在不知道你的字符集的情况下,我们无法说出那是什么;它通常"通常" 1 UTF-8中的字符,UTF-16中所有字符的字符串,等等。但是InputStreamReader
允许自己摆出空间来提前读取效率,这是一些不确定的数量。
如果你正在使用UTF-8(一个常见的默认值)并发送四个字节[0, 0, 0, 8]
,那么这些字符对应于四个字符:[\u0000, \u0000, \u0000, \u0008]
。在这种情况下,发送一个4字节的整数将导致你接收4个字符是有意义的。
答案 1 :(得分:0)
发送函数是否将字节转换回字符?
read
州Reads a single character.
。
发送:您正在写一个 4字节整数,显然由字节0,0,0,8组成。
阅读:每次只读两个字节,一个字符。
private char cb[];
...
return cb[nextChar++];
因此,要么只写两个字节,要么读取4个字节并将它们解释为4位整数。
我们需要更多代码来回答原始问题。
答案 2 :(得分:0)
BufferedReader.read()每次调用消耗一个字符的字节值。每个字符的字节数取决于字符编码。在大多数平台上,默认字符编码类似于UTF-8,每个字符通常只使用一个字节。
请注意,平台字符编码可能与Java的字符内部表示不同,后者每个字符使用两个字节。
答案 3 :(得分:0)
BufferedReader.read()的行为与Reader.read()中描述的相同。 唯一的区别是,如果缓冲区为空,它只从底层流中读取数据。
字节转换为字符,但这取决于字符集。如果字符集是UTF-8且一个字节大于127,则会收到少于4个字符。