0

我们正在实施一项功能,以支持我们的数据库中的 UTF-8 不可打印字符。我们的系统将它们存储在数据库中并检索它们。我们以 base 64 的形式收集输入,将它们转换为字节数组并存储在数据库中。在检索过程中,数据库为我们提供了字节数组,我们再次将它们转换为 base 64。

在检索过程中(在 db 给我们字节数组之后),所有属性都转换为字符串数组,然后它们再次转换回字节数组,并再次转换为 base 64 以将其返回给用户。

以下代码在我们的 Windows JDK(Java 8 版本)中编译并正常工作。但是当这个放在SuSe Linux环境中时,我们看到了奇怪的字符。

public class Tewst {
    public static void main(String[] args) {
        byte[] attributeValues;
        String utfString ;

        attributeValues = new byte[]{-86, -70, -54, -38, -6};
        if (attributeValues != null) {
            utfString = new String(attributeValues);
            System.out.println("The string is "+utfString);
        }
    }
}

给出的输出是

"字符串是 ªºÊÚú"

现在,当在 SuSe Linux 发行版上运行相同的文件时,它给了我:

“字符串是������”

我们在 Windows 和 Linux 中都使用 Java 8。它在Linux中无法正常执行的问题是什么?

我们也试过了 utfString = new String(attributeValues,"UTF-8");。它没有任何帮助。我们缺少什么?

4

1 回答 1

1

字符ªºÊÚú是 Unicode 00AA 00BA 00CA 00DA 00FA

在字符集ISO-8859-1中,即字节AA BA CA DA FA。如您在代码中所使用的那样,
以十进制表示。{-86, -70, -54, -38, -6}

所以,你的字符串是用 ISO-8859-1 编码的,而不是 UTF-8,这也是它在 Linux 上不起作用的原因,因为 Linux 使用 UTF-8,而 Windows 使用 ISO-8859-1。

永远不要使用new String(byte[]),除非你绝对确定你想要 JVM 的默认字符集,不管它是什么。

将代码更改为new String(attributeValues, StandardCharsets.ISO_8859_1).
当然,在反向操作中,使用str.getBytes(StandardCharsets.ISO_8859_1).
然后应该在各种平台上始终如一地工作,因为代码不再使用平台默认值。

于 2017-06-09T05:36:18.503 回答