2

为什么在 Linux 和 Windows 中显示以下内容不同?

System.out.println(new String("¿".getBytes("UTF-8"), "UTF-8"));

在 Windows 中:

¿

在 Linux 中:

一种

4

5 回答 5

15

System.out.println() 以系统默认编码输出文本,但控制台根据其自己的编码(或“代码页”)设置解释该输出。在您的 Windows 机器上,这两种编码似乎匹配,但在 Linux 机器上,输出显然是 UTF-8,而控制台将其解码为单字节编码,如 ISO-8859-1。或者,正如 Jon 建议的那样,源文件被保存为 UTF-8 并将javac其作为其他内容读取,这个问题可以通过使用 Unicode 转义来避免。

当您需要输出 ASCII 文本以外的任何内容时,最好的办法是使用适当的编码将其写入文件,然后使用文本编辑器读取文件——控制台太有限且太依赖系统。顺便说一下,这段代码:

new String("¿".getBytes("UTF-8"), "UTF-8")

...对输出没有影响。所做的只是将字符串的内容编码为字节数组并再次对其进行解码,从而再现原始字符串——这是一个昂贵的空操作。如果要以特定编码输出文本,则需要使用 OutputStreamWriter,如下所示:

FileOutputStream fos = new FileOutputStream("out.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
于 2008-10-06T23:49:22.730 回答
8

不确定问题到底出在哪里,但值得注意的是

¿ ( 0xc2,0xbf)

是用 UTF-8 编码的结果

0xbf,

这是 ¿ 的 Unicode 代码点

因此,在 linux 的情况下,输出没有显示为 utf-8,而是显示为单字节字符串

于 2008-10-06T21:19:47.183 回答
6

检查你的 linux 终端有什么编码。

对于 ubuntu 中的 gnome-terminal - 转到“终端”菜单并选择“设置字符编码”。

对于腻子,配置 -> 窗口 -> 翻译 -> UTF-8(如果这不起作用,请参阅这篇文章)。

于 2008-10-06T21:20:55.340 回答
2

运行此代码以帮助确定它是编译器问题还是控制台问题:

public static void main(String[] args) throws Exception {
    String s = "¿";
    printHex(Charset.defaultCharset(), s);

    Charset utf8 = Charset.forName("UTF-8");
    printHex(utf8, s);
}

public static void printHex(Charset encoding, String s)
        throws UnsupportedEncodingException {
    System.out.print(encoding + "\t" + s + "\t");

    byte[] barr = s.getBytes(encoding);
    for (int i = 0; i < barr.length; i++) {
        int n = barr[i] & 0xFF;
        String hex = Integer.toHexString(n);
        if (hex.length() == 1) {
            System.out.print('0');
        }
        System.out.print(hex);
    }
    System.out.println();
}

如果每个平台上 UTF-8 的编码字节不同(应该是c2bf),这是编译器问题。

如果是编译器问题,请将 "¿" 替换为"\u00bf"

于 2008-10-06T21:34:02.893 回答
1

由于您的编辑器和编译器编码,很难确切地知道您的源代码包含哪些字节,或者调用 getBytes() 的字符串。

您能否生成一个简短但完整的程序,其中仅包含 ASCII(以及在字符串中转义的相关 \uxxxx)仍然显示问题?

我怀疑问题很可能出在 Windows 或 Linux 上的控制台输出上,但最好先获得一个可重现的程序。

于 2008-10-06T21:10:29.073 回答