Java控制台应用程序中的Unicode输入

Java控制台应用程序中的Unicode输入,java,unicode,console-application,Java,Unicode,Console Application,我一直在尝试在Java应用程序中检索“unicode用户输入”,以获取一个小的实用程序片段。问题是,它似乎在Ubuntu“开箱即用”上工作,我猜它在UTF-8上有操作系统范围的编码,但在Windows上从“cmd”运行时不起作用。考虑中的守则如下: public class SerTest { public static void main(String[] args) throws Exception { testUnicode(); } publi

我一直在尝试在Java应用程序中检索“unicode用户输入”,以获取一个小的实用程序片段。问题是,它似乎在Ubuntu“开箱即用”上工作,我猜它在UTF-8上有操作系统范围的编码,但在Windows上从“cmd”运行时不起作用。考虑中的守则如下:

public class SerTest {

    public static void main(String[] args) throws Exception {
        testUnicode();
    }

    public static void testUnicode() throws Exception {
        System.out.println("Default charset: " +
           Charset.defaultCharset().name());
        BufferedReader in  =
           new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
        System.out.printf("Enter 'абвгд эюя': ");
        String line = in.readLine();
        String s = "абвгд эюя";
        byte[] sBytes = s.getBytes();
        System.out.println("strg bytes: " + Arrays.toString(sBytes));
        byte[] lineBytes = line.getBytes();
        System.out.println("line bytes: " + Arrays.toString(lineBytes));
        PrintStream out = new PrintStream(System.out, true, "UTF-8");
        out.print("--->" + s + "<----\n");
        out.print("--->" + line + "<----\n");
    }

}
Eclipse控制台中的输出(使用JAVA工具选项后):

me@host> javac SerTest.java  && java SerTest
Default charset: UTF-8
Enter 'абвгд эюя': абвгд эюя
strg bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
line bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
--->абвгд эюя<----
--->абвгд эюя<----
E:\>chcp 65001
Active code page: 65001

E:\>java -Dfile.encoding=utf8 SerTest
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=utf8
Default charset: UTF-8
Enter 'абвгд эюя': юя': ': абвгд эюя
strg bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
Exception in thread "main" java.lang.NullPointerException
        at SerTest.testUnicode(SerTest.java:26) # byte[] lineBytes = line.getBytes();
        at SerTest.main(SerTest.java:15)
Default charset: UTF-8
Enter 'абвгд эюя': абвгд эюя
strg bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=utf8
line bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
--->абвгд эюя<----
--->абвгд эюя<----
Default charset: UTF-8
Enter 'абвгд эюя': абвгд эюя
strg bytes: [-48, -80, -48, -79, -48, -78, -48, -77, -48, -76, 32, -47, -115, -47, -114, -47, -113]
line bytes: [-61, -112, -62, -80, -61, -112, -62, -79, -61, -112, -62, -78, -61, -112, -62, -77, -61, -112, -62, -76, 32, -61, -111, -17, -65, -67, -61, -111, -59, -67, -61, -111, -17, -65, -67]
--->абвгд эюя<----
--->абвгд �ю�<----
默认字符集:UTF-8
输入“бббΓэю”:ббΓэю
strg字节:[48,-80,-48,-79,-48,-78,-48,-77,-48,-76,32,-47,-115,-47,-114,-47,-113]
选择JAVA工具选项:-Dfile.encoding=utf8
行字节:[-48,-80,-48,-79,-48,-78,-48,-77,-48,-76,32,-47,-115,-47,-114,-47,-113]

--->абвгд эюяабвгд эюяабвгд эюяабвгд Ñ�ÑŽÑ� 当您试图调用
Arrays.toString(lineBytes)
时,会抛出NPE,这意味着
lineBytes
为空

lineBytes
保存值:
line.getBytes()
getBytes()
仅当内部抛出
UnsupportedEncodingException
时才能返回null

这种情况发生在windows上,因为默认情况下windows命令提示符不支持unicode。这在Ubuntu上有效,因为它的命令提示符完全支持unicode。它部分与eclipse配合使用,因为eclipse的控制台窗口是一个java组件,支持unicode输入,并使用java_工具_选项进行输出

底线是您希望将windows命令提示符配置为能够使用unicode字符。我看到了关于这个话题的几次讨论。请看一下这个:

我希望这对你有帮助

一些注意事项:

  • -Dfile.encoding=utf8
    是并可能导致意外的副作用:
J2SE平台规范不需要“file.encoding”属性;这是Sun实现的内部细节,不应该由用户代码检查或修改。它也是只读的;技术上不可能在命令行上或在程序执行期间的任何其他时间支持将此属性设置为任意值

  • 该类将检测并使用终端编码,但不支持Windows上的65001(UTF-8)-至少,上次我尝试时它没有
我相信,将Unicode与cmd.exe结合使用的正确且有文档记录的方法是使用和

当我看到这篇文章时,我写了几篇博文:


这就是路。我不认为有人能对这个答案做任何补充。谢谢你的回复。几点澄清:NPE是因为在
line
上调用
getBytes()
,这意味着
line
为空,这没有多大意义。我可以确认没有抛出
不支持的编码异常
(至少我没有看到)。最后,我尝试了链接线程中提到的建议,同样的结果。知道这里会发生什么事吗?@佐助,我想你错了。查看堆栈跟踪:在SerTest.testUnicode(SerTest.java:26)行.getBytes();在SerTest.main(SerTest.java:15)中,这意味着main()和NPE抛出点之间有11行。这就是
byte[]lineBytes=line.getBytes()
.Hi Alex,我知道它是
line.getBytes()
,因为我添加了一个新行
System.out.println(line)
,它给了我
null
。另外,如果您使用的是Windows,如果您能运行相同的代码并让我知道它是否适用于您,我将不胜感激。谢谢。啊,在编写windows命令行应用程序时,基本上没有一种读写unicode代码的明智方法?我在这里调试sun的UTFEncoder/解码器。*软件包……据我所知,没有跨平台的方式。有很多第三方控制台库,可以为所有平台提供一个通用的编写界面,但我不知道它们对I18N的支持级别。谢谢。我想我将不得不研究一些流行的curses实现(比如这个:),并希望它们以一种理智的方式处理unicode。认可的!