在一个简单的服务器客户端应用程序中,我以这种方式读取数据:
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
是 in.read()
返回的 char
:
Log.debug("Received character: "+current+" ["+(int)current+"]");
显然我对发生的事情感到困惑。发送函数是否将字节转换回字符?
在调试过程中,我发现了一个有趣的事情 - netbeans 控制台中的 \0
可以与其他文本一起复制。粘贴时,只会粘贴第一个\0
之前的数据。 (Windows 7)
最佳答案
Reader
读取 char
,而不是 byte
。它通常通过读取字节并将其转换为 char
来实现这一点(最终取决于读取器、其委托(delegate)等),无论是通过您手动指定的字符集,还是通过系统默认值。 InputStreamReader
一般是这种情况发生的地方。来自该类的 javadocs:
Each invocation of one of an InputStreamReader's read() methods may cause one or more bytes to be read from the underlying byte-input stream. To enable the efficient conversion of bytes to characters, more bytes may be read ahead from the underlying stream than are necessary to satisfy the current read operation.
所以答案确实是,“它是由实现定义的”,但至少需要形成一个字符所需的字节数。在不知道您的字符集的情况下,我们无法说出那是什么; 1 表示 UTF-8 中的“常用”字符,2 表示 UTF-16 中的所有字符,等等。但是 InputStreamReader
允许自己有一定的回旋空间,可以提前读取某些不确定的量,以提高效率。
如果您使用 UTF-8(常见的默认值)并发送四个字节 [0, 0, 0, 8]
,那么它们对应于四个字符:[\u0000,\u0000,\u0000,\u0008]
。在这种情况下,发送 4 个字节的整数会导致您收到 4 个字符,这是有意义的。
关于java - BufferedReader 使用 .read() 方法实际读取了多少字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24020006/