我做什么:
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 中得到的内容:
我在 Windows 控制台中得到的内容:
我有 Windows 10(俄语语言环境),控制台中的 Cp866 默认编码,IDE 中的 UTF-8 编码。 如何使控制台中的字符看起来正确?
实际上这里有两个问题:
Java 将输出转换为其默认编码,通常与控制台编码无关。这显然只能在虚拟机启动时被覆盖,例如
java -Dfile.encoding=UTF-8 MyClass
控制台窗口必须使用 TrueType 字体才能显示 Unicode。然而,Consolas 和 Lucida Console 都没有 ☐ 或 ☒。因此,它们显示为带有 Lucida Console 的方框和带有 Consolas 的问号方框(即 missing glyph 字形)。输出仍然很好,您可以轻松复制/粘贴它,只是看起来不太正确,并且由于 Windows 控制台不使用字体替换(无论如何都很难使用字符网格做到这一点),因此您无能为力让他们出现。
我可能只会使用
[█]
、[ ]
和 [X]
来代替。
控制台中的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 和 Windows 控制台,但如果您想让它在控制台字符输出和常规字节输出之间切换,则需要一些额外繁琐的工作命令管道。
然后你必须希望用户有非光栅字体(正如@Joey提到的),然后然后你必须希望字体具有你想要的字符的字形(Consolas不适用于U+2610或U+22612)。除非你真的必须这样做,否则让 Windows 控制台执行 Unicode 很大程度上是浪费你的时间。