如何在 ubuntu VM 上的 java 中将字节解码为 UTF-8



以下代码片段适用于我的 Linux 桌面:

public static void main(String[] args) throws IOException {
    byte[] bytes = new byte[] { -61, -77 };
    String string = new String(bytes, StandardCharsets.UTF_8);
    store(bytes, "/tmp/bytes");
    store(string.getBytes(StandardCharsets.UTF_8), "/tmp/string");
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.write(bytes);
    String other = baos.toString(StandardCharsets.UTF_8.name());
    store(other.getBytes(StandardCharsets.UTF_8), "/tmp/other");
    checkResult(string);
    checkResult(other);
}
private static void store(byte[] bytes, String path) throws IOException, FileNotFoundException {
    try (FileOutputStream os = new FileOutputStream(new File(path))) {
        os.write(bytes);
    }
}
private static void checkResult(String string) throws Error {
    System.out.println(string);
    if (!string.equals("ó")) {
        throw new Error("invalid: " + string);
    }
}

它创建3个文件,每个文件包含一个ó。它还打印 ó 两次。但是,当我在服务器 VM 上运行此代码时。然后控制台显示?符号而不是ó

3.13.0-116-generic #163~precise1-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux
$ java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-3~12.04-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

像这样运行示例代码段可以解决控制台问题:

java -Dfile.encoding=UTF-8 -jar weird.jar

实际的tomcat应用程序调用javamail,它发送带有?符号的电子邮件。我可以通过在JAVA_OPTS中设置以下属性来解决所有问题:-Dfile.encoding=UTF-8

但是,我在某处读到我永远不应该碰这个属性,因为它会以奇怪的方式破坏依赖项。

我现在工作。剩下的唯一问题是是否有一种更可接受的方法来做到这一点(而不会有依赖关系中断的风险(。

调用String.getBytes()几乎从来都不是一个好主意。

总是在Charset中通过. 通常,最好写

import static java.nio.charset.StandardCharsets.UTF_8;
...
string.getBytes(UTF_8);

在您的情况下,getBytes很可能正在尝试使用 UTF-8 以外的其他字符集,这导致了恶作剧。

最新更新