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

我一直在尝试在我的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 + "" + 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”输入?

很抱歉这个冗长的问题,并提前感谢,
佐助

一些说明:

  • -Dfile.encoding=utf8 不受支持 ,可能会导致意外的副作用:

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

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

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

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

  • I18N:Windows命令提示符下的Unicode
  • Java:Windows命令行上的Unicode

当您尝试调用Arrays.toString(lineBytes) ,NPE会抛出,这意味着lineBytes为null。

lineBytes包含值: line.getBytes() 。 只有在抛出UnsupportedEncodingException getBytes()才能返回null。

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

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

我希望这能帮到您。