【问题标题】:UTF-8 string converts non english character to invalid characterUTF-8 字符串将非英文字符转换为无效字符
【发布时间】:2018-09-14 04:08:19
【问题描述】:

我正在使用 UTF-8 编码将字节数组转换为字符串

new String(bytearray, StandardCharsets.UTF_8));

它将字符串Impresión 更改为Impresi�n。但是如果我执行下面的代码

new String(bytearray);

它将正确的字符串Impresión 提供给Impresión

我想在不将任何非英文字符更改为无效字符的情况下制作 UTF-8 编码字符串。

任何帮助将不胜感激。

【问题讨论】:

  • docs.oracle.com/javase/8/docs/api/java/lang/… - “通过使用平台的默认字符集解码指定的字节数组来构造一个新的字符串。”您的平台默认字符集可能不是 UTF-8(例如 Windows)。如果您的字符串在您平台的默认字符集中,而不是 UTF-8,那么这种行为是可以理解的。
  • 你确定Impresi�n 不只是输出你的stings 的shell 的产物吗?前段时间我在使用 mysql 和 bash 时遇到过这样的幻影问题。
  • @luksch 我确定它不是来自 shell 输出...
  • � 是对您指定的编码无效的字节的替换字符。在这种情况下,它确实对您有所帮助(尽管 IMO 例外会更好)。 � 向您的用户表明您对他们的数据处理不当并丢失了一些数据。那么,bytearray 中文本的字符编码是什么?
  • 嗨@TomBlodget。这是西班牙语文本,我正在尝试从字节数组转换为字符串。使用 UTF_8 时,会产生无效字符。

标签: java arrays string encoding utf-8


【解决方案1】:

Java 中的字符串对象使用 UTF-16 编码,不能修改。

如果您需要使用替代编码中的字符,则必须使用 byte[] 数组来存储数据,并且在将其转换为字符串时,请确保指定用于对字节数组。

因此,当您从字节数组构造字符串时,您必须确保字符串知道如何将其从原始编码编码为 UTF-16。这就是为什么您的第一个代码在构造函数中不起作用的原因,因为您指定了原始编码是什么,并且显然它不是正确的编码,因此 java 无法正确解码字节数组。但是在第二个代码中,您没有指定编码,因此 java 使用了系统上的默认编码,这可能与用于编码字节数组的编码相同,因此会产生正确的字符。

要解决此问题,请确保使用您在将字节数组解码为字符串时指定的相同编码对字节数组进行编码。

有关更多信息,请参阅以下链接,尤其是他们使用 UTF-16 编码编写的有关字符串的介绍:

https://docs.oracle.com/javase/7/docs/api/java/lang/String.html

【讨论】:

  • 我不知道其他编码中的字符在 unicode 中不存在 - 因此在 UTF-16 中不存在。所以是的,您可以将来自其他编码的字符存储在 java 字符串中,但您必须注意正确转换...
【解决方案2】:

格式会发生变化,因为您的源字节数组不是 UTF-8 编码的。 下面的代码对我来说很好。

    byte[] bytearray = "Impresión".getBytes(StandardCharsets.UTF_8);
    String s = new String(bytearray, StandardCharsets.UTF_8);
    System.out.println(s);

输出是

Impresión

但是当我运行下面的代码时

byte[] bytearray = "Impresión".getBytes();
String s = new String(bytearray, StandardCharsets.UTF_8);
System.out.println(s);

打印出来

Impresi?n

您需要使用相同的字符集进行编码和解码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 2014-03-07
    • 2018-12-05
    • 1970-01-01
    • 2016-09-08
    • 2013-03-02
    相关资源
    最近更新 更多