【问题标题】:How does inputstream per byte reading work?每个字节读取的输入流如何工作?
【发布时间】:2019-09-24 17:01:46
【问题描述】:

我无法理解 System.in.read() 方法的工作原理。

有这样一段代码:

    public static void main(String[] args) throws IOException {
        while (true){
            Integer x = System.in.read();
            System.out.println(Integer.toString(x, 2));
        }

我知道 System.in.read() 方法从输入流中读取每一个字节。

所以当我输入'A'(U+0041, 一个字节用于存储char) - 程序输出为:

 1000001 (U+0041)
 1010 (NL) - it works as expected.

但是当我输入 'Я'(U+042F, 两个字节用于存储字符) - 输出是:

 11010000 (byte1)
 10101111 (byte2)
 1010 (byte3 - NL)

字母'Я'(U+042F)的真实编码是10000101111。

为什么 11010000 10101111 (byte1 + byte2) 不是字母 'Я'(U+042F) 的二进制代码?

【问题讨论】:

  • 因为11010000 10101111是用UTF-8编码的Unicode字符U+042F。
  • 一个文本流编码二进制字符。您的输入流可能是 UTF8 格式,否则 ASCII 范围不会是单字节,但也会有 00 部分。阅读有关 UTF-8 的信息。
  • 'A' 在单字节范围内:十进制值 65,完全在单字节的 -128 到 127 数字范围内。 'Я' 是多字节的,因为十进制值 1,071 不能用单个字节表示。
  • 附带说明,您应该在此处使用int。没有理由将值装箱到 Integer 对象中。

标签: java inputstream


【解决方案1】:

这取决于将数据发送到System.in 的外部进程。它可以是命令 shell、IDE 或其他进程。

在命令外壳的典型情况下,外壳将配置字符编码。 (chcp 在 Windows 上,locale charmap 在 Linux 上。)

字符编码决定了图形字符或字形如何编码为数字。例如,Windows 机器可能使用"Windows-1251" 的“代码页”并将“Я”编码为一个字节(0xCF)。或者,它可以使用 UTF-8 并将“Я”编码为两个字节 (0xD0 0xAF),或者使用 UTF-16 并使用两个不同的字节 (0x04 0x2F)。

您的结果表明,向您的 Java 程序发送数据的进程使用 UTF-8 作为编码。

【讨论】:

    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2014-09-02
    • 2012-04-09
    相关资源
    最近更新 更多