请解释一下为什么当你在控制台输入字母't'然后输出System.in.read()andnew BufferedReader(new InputStreamReader(System.in)).read()时,当转换为type时你得到相同的结果int,即:116。毕竟字节流的标准read()必须读取一次一个字节,并返回零(作为两字节“t”记录的第一个字节),字符 BufferedReader 正确返回所有内容。
怎么了?
请解释一下为什么当你在控制台输入字母't'然后输出System.in.read()andnew BufferedReader(new InputStreamReader(System.in)).read()时,当转换为type时你得到相同的结果int,即:116。毕竟字节流的标准read()必须读取一次一个字节,并返回零(作为两字节“t”记录的第一个字节),字符 BufferedReader 正确返回所有内容。
怎么了?
控制台发送就绪字节。
System.in是由操作系统控制的 Java 进程的输入流。控制台将已转换的字节发送到此流。在控制台中输入数据时会发生什么:
设置编码取决于各个控制台/操作系统。
您的控制台很可能具有转换
t为一个字节的编码。System.in.read诚实地读取接收到的字节。InputStreamReader根据默认编码将接收到的字节转换为字符;您选择了一个未指定编码的构造函数。默认编码由 JVM 参数设置。您可以使用以下代码检查阅读器的编码:
可以使用构造函数之一显式设置编码。
读取时,读取器从输入流中读取字节,并根据编码转换成对应字符(char)的数值。根据 Java 规范 ( §3.1 Unicode ),字符以 UTF-16 编码存储。假设我们使用单字节编码,输入字符“s”并处理它:
Reader 将从输入流中读取一个字节,了解它是什么类型的字符,在 UTF-16 表中找到该字符并返回其数值。因此,此代码将等效于:
无论编码如何。
双字节编码
要查看标准输入的双字节编码,需要设置相应的编码。为了节省空间,大多数编码中的英文字符都被编码为一个字节。
这就是字符在高位到低位双字节编码(例如,UTF16-BE)中的转换方式。因此,为了看到这样的转换,
System.in.read您需要以这样的编码向输入提交数据。这可以通过多种方式完成,例如:
阅读控制台文档以了解如何为其设置编码以及是否支持 UTF16-BE 编码。如果是,则设置编码。如果没有,那么这种方法将不起作用。
不要从控制台输入数据,而是将文本文件传递给输入。以 UTF16-BE 编码保存文件,然后运行如下命令:
您需要考虑到保存文件中的第一个字符时将是BOM并跳过它。
将字符串显式转换为字节数组时:
在控制台中查看
字符串中数组的长度
"t"为 1,所需的字节为116.事实上,正如上面回答的@default locale 一样,
read()诚实地返回了这个字节。附言
以两字节字符为例
"ы",该方法getBytes()给出了一个两字节数组[-47, -117],如果我们使用该方法从流中读取这个字符System.in.read(),也会得到两个字节209和139。为什么会这样,因为(我引用了“Java Programming”,Patrick Niemeyer,Daniel Leuk,2014 年第 4 版,第 568 页)转移字节值的模式很简单——显式
int转换为byte.(byte) 209和(byte) 139分别-47和-117。如果我们通过方法
read()从 type 流中读取BufferedReader,则返回字符编码,如文档中所述: