UTF-8 的不可打印字符 - SUSE Linux Java 不支持



我们正在实现一项功能来支持数据库中不可打印的 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");。它没有任何帮助。我们缺少什么?

字符ªºÊÚú是 Unicode00AA 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).
然后应该在各种平台上一致地工作,因为代码不再使用平台默认值。

最新更新