【问题标题】:How to create UTF16 Strings [duplicate]如何创建 UTF16 字符串 [重复]
【发布时间】:2020-08-10 15:44:41
【问题描述】:

有没有办法从头开始创建一个 UTF16 字符串,或者从一个不涉及一些奇怪的“hack”的实际 UTF8 字符串创建一个 UTF16 字符串,比如遍历每个字符并附加一个 00 字节以使其成为 UTF16 字符?

理想情况下,我希望能够做这样的事情:

String s = new String("TestData".getBytes(), StandardCharsets.UTF_16);

但这不起作用,因为字符串文字被解释为 UTF8。

【问题讨论】:

  • 这能回答你的问题吗? How to convert UTF8 string to UTF16 尤其是接受答案的第二部分
  • 你想在这里做什么?从概念上讲,字符串包含独立于任何编码的字符。仅当您转换为字节或从字节转换时,编码才变得相关。
  • @jhamon 还值得一提的是对此答案的赞成评论。真的不应该那样做。
  • @jhamon 这比我的解决方法要好,但它看起来仍然很难解决问题。
  • 如果您将 DB 值作为字符串获取,则已经出现问题。 Java中只有一种字符串;没有 UTF-16 字符串或 UTF-8 字符串之类的东西。

标签: java string encoding


【解决方案1】:

在 java 中,String 实例没有编码。 只是 - 将字符表示为字符,因此没有编码。

编码只是在转换中不是一回事:当您将一堆字符“转换”成一堆字节时,反之亦然 - 除非提供字符集,否则无法执行该操作。

以您的 sn-p 为例。它被打破。你写:

"TestData".getBytes().

这编译。那是不幸的;这是 java 中的 API 设计错误;你永远不应该使用这些方法(那就是:默默地掩盖涉及字符集的事实的方法)。这从字符(字符串)到字节的转换。如果您阅读getBytes() 方法的javadoc,它会告诉您将使用“平台默认编码”。这意味着它是编写代码的一个很好的公式,它可以通过您机器上的所有测试,然后在运行时失败。

需要平台默认编码是有正当理由的,但我强烈建议您无论如何都不要使用getBytes()。如果您遇到这些罕见的情况之一,请编写 "TestData".getBytes(Charset.defaultCharset()),以便您的代码明确表明此处正在发生使用字符集的转换,并且您希望它成为平台默认值。

所以,回到你的问题:没有像 UTF-16 字符串这样的东西。 (如果这里的“字符串”被认为是:java.lang.String,而不是俚语英语术语,意思是“字节序列”)。

字节序列之类的东西,表示以 UTF-16 格式编码的 unicode 字符。换句话说,Java 中的“UTF-16 字符串”看起来像byte[]。不是String

因此,您真正需要的是:

byte[] utf16 = "TestData".GetBytes(StandardCharsets.UTF_16);

你写:

但这不起作用,因为字符串文字被解释为 UTF8。

那是代码的属性,而不是字符串的属性。如果您有一些无法更改的代码,它将使用 UTF8 字符集将字符串转换为字节,并且您不希望这种情况发生,然后找到源并修复它。没有其他解决方案。

特别是,试图破解一些东西,比如你有一个带有 gobbledygook 的字符串,它具有疯狂的属性,如果你使用这个 gobbledygook,使用 UTF8 字符集将其转换为字节,然后将这些字节转换回使用 UTF16 字符集的字符串,你得到你真正想要的 - 不能工作。对于具有每个字节序列都可表示的属性的字符集,例如 ISO_8859_1,这在理论上是可能的(但确实是个坏主意),但 UTF-8 不遵守该属性。有些字节序列在 UTF-8 中只是一个错误,会导致异常。另一方面,不可能制作一个字符串,以便使用 UTF-8 将其解码为字节数组,从而产生特定的所需字节序列。

【讨论】:

  • 感谢您的信息,让我再补充一点。但是,还有一个额外的问题,您在上面创建字节数组的方式在实际数据之前附加了额外的四个字节。那四个字节是干什么用的?编辑:啊,这是编码本身,当我将其更改为 LE 或 BE 时,它会按我的预期表示:)
  • @David 这对 UTF-16 来说主要是一个独特的东西,它是一个“字节顺序标记”。几乎所有其他编码都不会这样做。从好的方面来说,任何以 0xFE 0xFF(或相反)开头的字节流都可能是 UTF-16 数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2017-11-23
  • 2015-05-28
  • 2014-12-23
  • 1970-01-01
  • 2012-11-04
相关资源
最近更新 更多