【问题标题】:How to print Unicode symbols U+2610 and U+2612 to Windows console with Java?如何使用 Java 将 Unicode 符号 U+2610 和 U+2612 打印到 Windows 控制台?
【发布时间】:2017-05-19 17:11:52
【问题描述】:

我做什么:

public class Main {
    public static void main(String[] args) {
        char i = 0x25A0;
        System.out.println(i);
        i = 0x2612;
        System.out.println(i);
        i = 0x2610;
        System.out.println(i);
    }
}

我在 IDE 中得到的: What I get in IDE

我在 Windows 控制台中得到的信息: What I get in Windows console

我有 Windows 10(俄罗斯语言环境),控制台中的 Cp866 默认编码,IDE 中的 UTF-8 编码。 如何使控制台中的字符看起来正确?

【问题讨论】:

  • 切换 chcp 65001 和字体更改没有帮助
  • 哦,那我很抱歉。我试着帮你查了
  • 你知道你可以写System.out.println("\u25A0");,而不是通过Character.toString跳舞吗? (也可以写System.out.println(i);或char i = 0x25A0;)。

标签: java windows unicode console cyrillic


【解决方案1】:

控制台中的CP866默认编码

嗯,是的。代码页 866 不包括字符 U+25A0、U+2610 或 U+2612。因此,即使 Java 为控制台使用了正确的编码(可能是因为您设置了 -Dfile.encoding=cp866 之类的内容,或者它猜到了正确的编码,但它几乎永远无法管理),您也无法将字符输出。

如何使控制台中的字符看起来正确?

你不能。

理论上您可以使用-Dfile.encoding=utf-8,并将控制台编码设置为UTF-8(或足够接近,代码页65001)。不幸的是,Windows 控制台因多字节编码而损坏(除了传统的语言环境默认支持的编码,UTF-8 不支持);你会得到乱码输出并挂起输入。这种方法通常是行不通的。

让 Unicode 进入 Windows 控制台的唯一可靠方法是跳过 Java 使用的基于字节的 C 标准库 I/O 函数,直接进入 Win32 本机 WriteConsoleW 接口,该接口接受 Unicode 字符(嗯, UTF-16 代码单元,与 Java 字符串相同),因此避免了字节转换中的控制台错误。您可以使用 JNA 访问此 API — 请参阅此问题中的示例代码:Java, UTF-8, and Windows console,但如果您想让它在控制台字符输出和命令管道的常规字节输出之间切换,则需要一些额外的繁琐工作。

然后然后你必须希望用户有非光栅字体(正如@Joey提到的那样),然后那么你必须希望字体有字符的字形你想要的(Consolas 不适用于 U+2610 或 U+22612)。除非您真的必须这样做,否则让 Windows 控制台执行 Unicode 在很大程度上是在浪费您的时间。

【讨论】:

  • 好点子,我实际上忘记了 Java 在下面使用非广泛的 C API,这本身就是一个有趣的问题来源 ;-)
  • @Joey:是的,而且比这更糟糕:即使使用广泛的 C 标准库 API,默认情况下也会被破坏。您可以使用_setmode(stream, _O_U8TEXT) 对其进行某种修复,但是您将永远无法使用窄流 API,因为它们会崩溃。我想Java可能不会高兴。 :-) 这真是一场可怕的灾难
【解决方案2】:

其实这里有两个问题:

  1. Java 将输出转换为其默认编码,通常与控制台编码没有任何关系。这显然只能在 VM 启动时被覆盖,例如

    java -Dfile.encoding=UTF-8 MyClass
    
  2. 控制台窗口必须使用 TrueType 字体才能显示 Unicode。但是,Consolas 和 Lucida Console 都没有 ☐ 或 ☒。因此,它们显示为带有 Lucida Console 的框和带有问号的带有 Consolas 的框(即 缺少的字形字形)。输出仍然很好,您可以轻松地复制/粘贴它,只是看起来不正确,而且由于 Windows 控制台不使用字体替换(无论如何用字符网格很难做到这一点),您几乎无能为力让他们出现。

我可能只使用[█][ ][X]

【讨论】:

  • 我之前试过 -Dfile.encoding=UTF-8 和 -Dfile.encoding=Cp866 ,没有任何帮助。感谢您的想法。
  • 好吧,Cp866 不会有任何好处,因为字符不在那个代码页中
  • 好的,主要问题似乎是字体中没有字符。仍然有一个问题,为什么它在 IDE 中可以。我有一个想法,这是因为 Windows 对图形和控制台输出使用不同的编码,但我不确定
  • 您的 IDE 可能不会将控制台输出视为字符单元格的网格,而是将其视为文本流(在 Unix 中很常见,但在 Windows 中则不然)并相应地显示它。因此它可能可以简单地使用正常的文本输出,从而进行字体替换。
【解决方案3】:

您确定您使用的字体具有显示 Unicode 的字符吗?没有字体支持所有可能的 Unicode 字符。例如,U+9744,9632 和 9746 不受支持。 Arial 字体。您也可以更改 IDE 控制台和 Windows 控制台的字体。

【讨论】:

  • 我不完全确定字体是否有字符,但我在 IDE 和控制台中使用了相同的字体“Consolas”和“Lucida Console”,每次在 IDE 中都是正确的,在控制台中是错误的。所以我想问题出在编码上。
  • 请更正您的代码示例。您使用的 Unicode 与您附加的图片不同。回到主题:您是否尝试更改控制台的代码页?使用命令 chcp 65001 将您的代码页更改为 65001。然后尝试键入 ALT + 02610(在小键盘上)。图标可见吗?
  • 更新了代码示例,在 IDE 和控制台中的结果相同。尝试了 chcp 65001 和 ALT + 02610,控制台中没有显示图标,只有数字“2”。
  • 因为他们得到问号,所以这(至少一开始)不是字体问题,而是编码转换破坏了输出。
  • 我做了一些研究。似乎 Java 正在重置控制台代码页。看看这个问题:stackoverflow.com/questions/8669056/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 2017-08-03
  • 2012-03-11
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多