从键盘读取UTF-8编码的内容

5
我需要从用户那里读取输入,并且我希望支持非拉丁字母,例如Å、Ä和Ö。
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, "UTF-8"), true);
out.println(keyboard.readLine());
out.println("Read with charset: " + Charset.defaultCharset().name());

当我运行这段代码并输入拉丁字母时,它按预期工作(我输入一些内容,按回车键,然后它打印出我输入的内容)。但是如果我尝试使用å,就会得到以下结果:
å

�
Read with charset: UTF-8

如果文本以非拉丁字母结尾,我必须按两次回车键,然后它无法正确显示。我已经在Netbeans的控制台和Windows命令提示符中尝试过,但都没有得到预期的结果。


我无法找到UTF-8的解决方案,但改用ISO-8859-1。它能在我的Netbeans控制台(应该是UTF-8)和CMD上正常工作,只需首先运行chcp 28591,更改字体(在我的情况下是必要的),然后运行程序。


https://dev59.com/zW445IYBdhLWcg3w_PG3 和 https://dev59.com/cWox5IYBdhLWcg3wVCxy - crAlexander
它对我有效。您的控制台必须设置正确,才能正确显示UTF-8。 - RealSkeptic
@RealSkeptic,我可以打印出非拉丁字符,没有问题(Sys.out.print("å"))。这在Netbeans控制台和CMD中都可以正常工作。但是当我尝试读取字符时,问题就出现了(以及当文本以å ä或ö结尾时需要按两次回车键)。 - Dan Lindqvist
尝试从System.in中仅读取字节并将其打印出来。这可以告诉您控制台设置的字符集是什么。 - RealSkeptic
所以它只发送了一个字节的 Å?这直接来自控制台,因此控制台设置为 ISO-8859-1 而不是 UTF-8。当读取器尝试将其解释为 UTF-8 时,它会弄乱它。尝试使用 new InputStreamReader(System.in, Charsets.ISO_8859_1) 替换您现在拥有的内容,我相信字符将被适当地读取(虽然我不确定它将如何打印出来,但您可以在调试器中检查它)。 - RealSkeptic
显示剩余4条评论
2个回答

1
代码示例无法正确编码。它使用系统默认方式从控制台读取数据,然后使用UTF-8将其写出。您的系统默认可能不是UTF-8,并且为了使事情更加复杂,您的控制台可能与您的系统默认不同。
在控制台中正确执行此操作,您需要使用控制台编码进行读取,并使用控制台编码进行写出。如果您只是在测试并需要写入文件,例如,请将其写为UTF-8,并确保使用文本编辑器以UTF-8打开。

Netbeans控制台是UTF-8编码,除非Netbeans存在错误。不过我已经找到了一个解决方法(请查看我的更新问题)。 - Dan Lindqvist

0
你尝试过吗:

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

如果这种方法不起作用,请尝试读取原始字节流,然后将其转换为new String(bytes,"UTF-8")

如果您没有指定字符集,那么它将使用默认字符集(在我的情况下是UTF-8,正如您在我的问题中所看到的)。我尝试了您的另一个建议,也尝试了读取原始字节,但没有成功。不过,我找到了一个解决方法(使用ISO-8859-1代替)。 - Dan Lindqvist
真不敢相信它使用的是ISO-8859-1而不是UTF-8。我以为UTF-8现在已经很普遍了,但也许并不是这样。 - TV Trailers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接