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

时间:2011-12-29 14:28:36

标签: java unicode console-application

我一直在尝试在我的Java应用程序中检索“unicode用户输入”以获取一个小实用程序代码段。问题是,它似乎正在Ubuntu“开箱即用”,我猜想在UTF-8上运行OS宽编码,但从“cmd”运行时无法在Windows上运行。考虑的代码如下:

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");
    }

}

Ubuntu上的输出(不对配置进行任何更改):

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]
--->абвгд эюя<----
--->абвгд эюя<----

Windows CMD提示输出(绝不受JAVA_TOOL_OPTIONS影响):

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)

Eclipse控制台中的输出(使用JAVA_TOOL_OPTIONS后):

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]
--->абвгд эюя<----
--->абвгд эюя<----

在Eclipse控制台上,它正在工作,因为我添加了一个系统范围的环境变量(JAVA_TOOL_OPTIONS),如果可能的话我想避免。

Eclipse控制台中的输出(在删除 JAVA_TOOL_OPTIONS之后):

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]
--->абвгд эюя<----
--->абвгд �ю�<----

所以我的问题是:究竟正在进行什么?需要进行哪些代码更改才能确保此代码段适用于各种“Unicode”输入?

对不起啰嗦的问题表示歉心,并提前致谢,
佐助

2 个答案:

答案 0 :(得分:4)

一些注意事项:

  • -Dfile.encoding=utf8not supported,可能会导致意外的副作用:
  

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

  • Console类将检测并使用终端编码,但在Windows上不支持65001(UTF-8) - 至少,它不是我最后一次尝试它

我认为使用Unicode和cmd.exe的正确记录方法是使用WriteConsoleWReadConsoleW

我在看这篇文章时写了几篇博文:

答案 1 :(得分:3)

当您尝试呼叫Arrays.toString(lineBytes)时,NPE会抛出,这意味着lineBytes为空。

lineBytes包含值line.getBytes()getBytes()只有在UnsupportedEncodingException被抛入内部时才能返回null。

它发生在Windows上,因为Windows命令提示符默认情况下不支持unicode 。这适用于Ubuntu,因为它的命令提示符是完全启用unicode的。它部分适用于eclipse,因为Eclipse的控制台窗口是一个java组件,它支持输入的unicode,并使用JAVA_TOOL_OPTIONS进行输出。

最重要的是,您希望配置Windows命令提示符以便能够使用unicode字符。我看到了关于这个主题的几个讨论。请看一下这个:Unicode characters in Windows command line - how?

我希望这会对你有所帮助。