Java windows控制台中的unicode字符数超出预期

Java windows控制台中的unicode字符数超出预期,java,windows,unicode,console,Java,Windows,Unicode,Console,我想在windows控制台中打印俄文和德文字符。 因此,我编写了一个小测试程序来了解它的工作情况: PrintStream ps = new PrintStream(System.out, false, "UTF-8"); ps.println("öäüß гджщ"); 然后我启动cmd.exe,将其字体更改为支持Unicode的Lucida Console,将代码页更改为带有“chcp 65001”的Unicode,并执行了我的程序 德文和俄文字符已打印,但文本比我预期的要多一些(红色下划

我想在windows控制台中打印俄文和德文字符。 因此,我编写了一个小测试程序来了解它的工作情况:

PrintStream ps = new PrintStream(System.out, false, "UTF-8");
ps.println("öäüß гджщ");
然后我启动cmd.exe,将其字体更改为支持Unicode的Lucida Console,将代码页更改为带有“chcp 65001”的Unicode,并执行了我的程序

德文和俄文字符已打印,但文本比我预期的要多一些(红色下划线):

但是文本在Eclipse控制台中打印正确。有没有办法在windows控制台中正确打印它? 我使用Windows7


我刚刚用JNI解决了这个问题,但对于纯java是否可行仍然很有趣。

每次打开或编写文件时,都会应用某种编码。但有时我们忘记了IDE(在您的例子中是Eclipse)也有一个编码

当您在引号之间键入某个文本时,它将以特定的编码(IDE的编码)显示和键入。 您的假设是,输出流的编码(UTF-8)也将保证文本以该特定编码显示。然而,我认为这里同样应用了IDE的编码

我建议再次检查您对eclipse的编码。也许这可以解决你的问题。当然值得一试,不是吗?:)

对于全局编码设置,请将以下代码添加到eclipse.ini文件

-Dfile.encoding=UTF-8 
编辑:

我只想补充以下几点。作为实验,我执行了以下步骤

  • 我打开Notepad++并创建了一个新文件
  • 我将编码设置修改为UTF-8
  • 我复制了你的俄语文本并将其粘贴到我的新文本文件中并保存了它
  • 接下来,我打开了我的windows控制台(“cmd”)
  • 我执行了“chcp 65001”命令
  • 接下来,我在控制台中打印了文件的内容:“type file.txt”
  • 一切都显示正确 这并不能证实多少,但它确实证实了这样一个事实,即如果内容采用正确的编码方式,DOS就可以完成这项工作

    EDIT2:

    @ka3ak已经两年多了,但在阅读一本关于Java I/O的书时,我偶然发现了以下内容

    System.console().printf(…)
    System.out.println(…)
    方法更好地支持特殊字符

    由于
    PrintStream
    只是围绕
    System.out
    流,我想您也有同样的限制。我想知道这是否能解决这个问题。如果仍然重要,请尝试一下。:)


    stackoverflow上的其他帖子也报告了类似的事情:

    在阅读了这里的答案和建议后,我得出结论,JRE肯定有问题。也许这个问题只存在于Windows 7中(不幸的是,我没有其他Windows系统可供试验)


    解决方案是使用JNI,或者如果您想要更简单的解决方案,那么就使用JNA。我发现了一个有用的JNA示例,它解决了我的问题,这里

    这是由于在Windows中实现了cp65001。请参阅中的完整披露


    简短总结:在Windows7之前,只有7位(原文如此!)输入/输出在cp65001中工作可靠(除非CRTL采取了变通办法)。Windows 8中修复了输出问题。Windows 10中存在输入问题。

    我查看了这一问题,但从未找到原因。我想原因隐藏在JRE原生代码中。afaik行为取决于windows版本。来自utf8everywhere.org:“在Windows 7上,控制台将该字符显示为两个无效字符,无论使用何种字体”@McDowell我认为你是对的,问题一定出在JRE中。@Pavel Radzivilovsky你的诊断非常准确。使用JNI或JNA可能没有其他解决问题的方法。请尝试使用SetConsoleOutputCP(CP_UTF8)并使用UTF-8进行输出。这应该行得通。我也尝试了你做的步骤,得到了同样的结果。选项“-Dfile.encoding=UTF-8”没有帮助。我得到了同样的错误文本。@Bvdb-问题在于
    System.out
    以及它如何写入标准输出。默认情况下,它使用系统的传统ANSI编码。试图使用UTF-8会导致不良行为。我还要注意的是,并非所有JRE的库都会尊重
    file.encoding
    属性,因为它不是一个标准属性。@McDowell我刚刚在某个地方读到
    System.console()
    System.out
    流更好地支持特殊字符。在某种程度上,这就是你两年前所说的仅供参考:类似的行为至少可以追溯到Windows XP。