Java 字符编码、ISO 到 UTF 转换

标签 java utf-8 character-encoding iso-8859-1 tibco-rv

这个主题已成为许多讨论的目标,但我们仍然看到新的主题出现。 我的场景如下:

在 Linux 服务器上运行的 Java 框架,其中 UTF-8 是 JVM 中的默认字符编码。该框架由一些接收要处理的 Tibco RV 消息的服务组成。其中一些消息包含非 ASCII 字符并从 Windows 服务器发送,ISO8859-1 是创建消息时使用的编码。 现在,当从 Tib rv 消息中提取数据时,有问题的字段作为 Java 对象“到达”,需要转换为字符串......在这里,我还无法提取包含非 ISO8859-1 字符串以正确的方式将 ASCII 字符(瑞典语“å”、“ä”、“ö”)转换为 UTF-8 字符串。 我尝试过使用以下方法:

String isoStreet = new String(response.get("street").toString().getBytes(StandardCharsets.ISO_8859_1),java.nio.charset.StandardCharsets.UTF_8);

我也尝试过使用 java.nio 包中的编码器/解码器,但没有成功。

同样有趣的是,我使用 PuttY 连接到托管并运行服务的服务器。从那里我可以从 shell 发出直接的 Tibco rv 请求(使用 tibcorvsend 客户端),并且似乎我需要在登录之前在 PuttY (Window_>Translation) 中将远程字符集设置为 ISO8859-1服务器并发出 Tib rv 请求 - 完成此操作后,无论我在远程 Linux 服务器中设置什么编码,这些非 ASCII 字符都会在响应中正确显示。 在这种情况下,使用“export LC_ALL=en_US.UTF-8”或“export LC_ALL=sv_SE.iso88591”并不重要...只有我在 PuttY 中设置的远程编码...

这应该意味着响应消息看起来不错,并且至少 shell 能够输出正确的字符。但是,当在 Java VM 内部(使用 Java 服务)时,我猜想在 Watch View 中调试和查看响应对象(不希望将其转换为字符串)时,响应字段会悄悄地插入字符串中...不确定您是否可以关注我,如果没有,我可能会在需要时尝试更清楚......

任何人对此问题的任何意见

问候 /R

最佳答案

一个character encoding指定如何将由字符组成的文本转换为字节,反之亦然。如您所知,有不同的字符编码,例如 ASCII、ISO-8859-1 和 UTF-8。

字符串由字符组成。在某些时候,您希望将这些字符转换为字节,以便可以通过网络发送它们、将它们存储在文件中或执行任何您想要执行的操作。您使用字符编码将字符串转换为字节。在另一端,您接收字节时,使用相同的字符编码将字节转换回字符串中的字符。

让我们看看为什么像您发布的那样的行是不正确的。让我们首先重写它,以便我可以解释各个部分:

String street = response.get("street").toString();
byte[] streetBytes = street.getBytes(StandardCharsets.ISO_8859_1);
String isoStreet = new String(streetBytes, StandardCharsets.UTF_8);

在第一行中,您从响应中获取一些数据并将其转换为字符串。 (response.get("street") 返回什么?)。

在第二行中,您使用 ISO-8859-1 字符集对该字符串进行编码。您将获得一个字节数组,其中包含字符串中字符的有效 ISO-8859-1 字符代码。

在第三行中,您将字节转换为字符串,并假设这些字节是 UTF-8 字节。这显然是错误的,因为字节是 ISO-8859-1 数据而不是 UTF-8 数据。当您这样做时,您可能会得到错误的字符,如果字节数组包含的字节序列根据 UTF-8 不是有效字符,甚至会出现异常。

需要注意的一件事是字符串仅由字符组成。字符串本身没有编码。您可以使用字符编码将字符串转换为字节,反之亦然。您不能“更改字符串的字符编码”,因为字符编码根本不是字符串的属性。就像数字本质上不是十进制或十六进制一样 - 这些只是表示同一数字的不同方式。

你需要做的是:

  • 在编写消息时,请确保使用正确的字符编码将字符串转换为字节。

  • 在阅读消息时,请确保使用正确的字符编码将字节转换为字符串。

不要使用平台的默认字符编码将某些内容读入字符串,然后尝试“转换字符串”。那是行不通的。

关于Java 字符编码、ISO 到 UTF 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28479462/

相关文章:

.net - Powershell – WriteAllLines 方法 – ‘Access is Denied’

C++迭代具有混合字符长度的utf-8字符串

Javascript 字符集问题

java - 从 Java 字符串中删除字符 e280a8

java - 求逆矩阵

java - 在 Web 浏览器中运行 Java 应用程序

java - 在weblogic上部署play框架

javascript - 如何查找文件编码和解码?

php - PHP 文件中的 UTF-8 BOM 签名

java - 使用 SQLite 写入的行数比预期少