UTF-8和UTF-16之间是否存在明显差异?

11

我调用了一个webservice,返回一个采用UTF-8编码的响应xml,我在Java中使用getAllHeaders() 方法来检查。

现在,在我的Java代码中,我对该响应进行一些处理。之后,将其传递给另一个服务。

我通过谷歌搜索发现,Java字符串默认的编码方式是UTF-16。

在我的响应xml中,有一个元素具有字符É。但是,在我向不同服务发出后处理请求时,该字符被破坏了。

它发送了一些乱码。我想知道这两种编码之间是否会有很大的区别?如果我想知道É将从UTF-8转换为UTF-16,我应该如何做?


你是如何读写XML的呢?使用JAXB?还是StAX?能否给出创建读取器和写入器的代码示例? - Puce
4个回答

37

UTF-8 和 UTF-16 都是可变长度编码。但是,在 UTF-8 中,一个字符至少占用 8 个比特,而在 UTF-16 中,字符长度从 16 比特开始。

主要的 UTF-8 优点:

  1. 基本 ASCII 字符(如数字、没有重音的拉丁字符等)占用一个字节,与 US-ASCII 表示相同。这样所有的 US-ASCII 字符串都成为合法的 UTF-8,这在许多情况下提供了良好的向后兼容性。
  2. 没有空字节,可以使用空结尾字符串,这也带来了很大程度的向后兼容性。

主要的 UTF-8 缺点:

  1. 许多常见字符具有不同的长度,这会极大地降低索引和计算字符串长度的速度。

主要的 UTF-16 优点:

  1. 大多数常见字符,如拉丁文、西里尔文、中文、日文等都可以用 2 个字节表示。除非真正需要外国语言字符,否则 UTF-16 的 16 位子集可以用作固定长度编码,这可以加快索引速度。

主要的 UTF-16 缺点:

  1. 许多 US-ASCII 字符串中有很多空字节,这意味着无法使用以 null 结尾的字符串,并且浪费了大量的内存。

通常情况下,UTF-16 通常更适合于内存表示,而 UTF-8 对于文本文件和网络协议非常好。


1
很好的回复。你能否满足我的好奇心,或许给UTF-32命名一个实际用途?我真的想不出它存在的原因。简单的谷歌搜索也没有帮助我更进一步,只有“速度优化”。 - Gimby
我有一个问题,可能非常琐碎。以简单记事本为例。假设我调用某个服务,返回给我UTF-8编码的数据。这基本上是所有ASCII或其他编码。现在我从Web服务中得到了一个字符,比如说'A'。现在这个A将被映射到UTF-8中的某个内容。例如00000000(8位)。现在,当记事本解释它时,它会将其转换为0000(4位)。现在,这不会让一切都变得混乱吗? - Kraken
请检查我下面的答案。 - Arjun Chaudhary
UTF-32可以说是Unicode编码形式中最易读的,因为它的大端十六进制表示仅仅是Unicode标量值,没有“U+”前缀,并且用零填充到八位数。 - Arjun Chaudhary
嗯...也许我不确定我想要问什么问题。也许稍后我会把它表达清楚,并在另一个主题中提问。 - Kraken

4
有两个要点:
  • 你交换数据时使用的编码方式;
  • Java 内部字符串表示。
你不应太过关注第二点 ;) 重要的是使用适当的方法将数据(字节数组)转换为String(最终的char数组),并将String转换为你的数据。你可以考虑最基本的类, CharsetDecoder CharsetEncoder ,但还有很多其他选择。 String.getBytes(),所有的 Reader Writer 都是其中两种可能的方法。 Character 的所有静态方法也是如此。 如果你看到了乱码,意味着你没有成功地将原始字节数据解码或编码为Java字符串。但是,Java字符串使用UTF-16这一事实在这里不相关。 特别需要注意的是,创建 Reader Writer 时,应该指定编码方式。如果没有这样做,则会使用默认的JVM编码,它可能是UTF-8,也可能不是。

2

本网站提供UTF到UTF转换

http://www.fileformat.info/convert/text/utf2utf.htm

UTF-32可以说是Unicode编码形式中最易于人类阅读的一种,因为它的大端十六进制表示仅仅是Unicode标量值,没有前缀“U+”,并且补零以八位数字表示。虽然UTF-32表示法使编程模型变得更加简单,但增加了平均存储大小,使得完全转换为UTF-32不太可行。

然而

UTF-32与旧的UCS-4编码相同并保持固定宽度。为什么可以保持固定宽度呢?因为UTF-16现在是可以编码最少数量字符的格式,它为所有格式设定了限制。定义1,112,064是将由Unicode或ISO 10646定义的所有代码点的总数。由于Unicode现在仅定义从0到10FFFF,因此UTF-32现在听起来有些无意义,因为它是32位宽的,但实际上只有约21位被使用,这使得其非常浪费。


0

UTF-8:一般来说,您应该使用UTF-8。大多数HTML文档都使用此编码。

它使用至少8位数据来存储每个字符。这可以导致更高效的存储,特别是当文本主要包含英语ASCII字符时。但是,高阶字符(例如非ASCII字符)可能需要每个字符最多24位!

UTF-16: 此编码使用至少16位来编码字符,包括低阶ASCII字符和高阶非ASCII字符。

如果您要编码的文本主要由非英语或非ASCII字符组成,则UTF-16可能会导致更小的文件大小。但是,如果您使用UTF-16来编码大部分ASCII文本,则会占用更多空间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接