从System.in流中读取和写入UTF-8字符

时间:2016-11-23 00:50:25

标签: java input unicode utf-8 inputstream

如果我使用AdalAuthenticationProvider流的print方法在控制台上打印像ελληνικά这样的unicode字符串,则按预期打印(因为我在输出控制台中使用Ubuntu mono)它支持UTF字符。)

但是,如果我尝试使用System.in流从控制台unicode字符读取UTF-8编码,则它无法正确读取。  我已经尝试了许多不同的方法来使用System.in流使用各种读取器类来实现它,但它永远不会工作。所以有人知道我可以这样做的方式

以下是代码示例

System.out

和我控制台上的输出:

BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
BufferedWriter console = new BufferedWriter(new OutputStreamWriter(System.out, "UTF-8"));

console.write("p1: Γίνεται πάντως\n");
console.flush();
System.out.println("p2: Γίνεται πάντως");

byte dataBytes[] = keyboard.readLine().getBytes(Charset.forName("UTF-8"));
System.out.println("p3: " + new String(dataBytes));
console.write("p4: " + new String(dataBytes, "UTF-8") + "\n");
console.flush();
Scanner scan = new Scanner(System.in, "UTF-8");

System.out.println("p5: " + (char) System.in.read());
System.out.println("p6: " + scan.nextLine());
System.out.println("p7: " + keyboard.readLine());

我的IDE是Netbeans

2 个答案:

答案 0 :(得分:1)

System.inInputStream,是一个字节流。您需要Reader才能读取字符。读者会为你做解码。

在这种情况下,您可以使用System.in包装InputStreamReader,并将“UTF-8”作为第二个构造函数参数传递。

Scanner console = new Scanner(new InputStreamReader(System.in, "UTF-8"));
while (console.hasNextLine())
    System.out.println(console.nextLine());

更新

你的标准输入的编码可能是错误的。要验证,您可以比较从System.in获得的字节数组和预期的字节数组。

byte [] expected = "Δέν".getBytes("UTF-8"); // [-50, -108, -50, -83, -50, -67]

byte [] fromStdin = new byte[1024];
int c = System.in.read(fromStdin);
for (int i = 0; i < c-1; i++) {
    if (expected[i] != fromStdin[i]) {
        System.out.println(i + ", " + fromStdin[i]);
    }
}

你输入“Δέν”(没有双引号)然后按回车键。如果它输出任何内容,则您的System.in编码错误。

  

System.in不应该与defaultCharset或某些系统属性具有相同的编码吗?

不一定。它是字节流,而不是字符流。它不能是字符流,因为您可以/应该能够提供二进制数据。无论你想要什么,图像或音频或视频。它必须支持这些。这就是为什么它只是一个InputStream这取决于环境给你的程序带来了什么。我对你的环境知之甚少。您需要了解如何更改环境,或找出实际为您的程序编码的编码。

例如,我们有一个UTF-16文本文件utf16.txt,我们将其内容提供给我们希望STDIN为UTF-8编码文本的程序:

java -cp ... our.utf8.Program < utf16.txt

它会读取乱码。

答案 1 :(得分:1)

尝试使用java.io.Console.readLine()java.io.Console.readLine(String, Object...)Console方法返回System.console()个实例。例如:

package package01;

import java.io.Console;

public class Example {

    public static void main(String[] args) {
        Console console = System.console();
        if (console == null) {
            System.err.println("No console");
            System.exit(1);
        }
        String s = console.readLine("Enter string: ");
        System.out.println(s);
    }

}