UTF-8 和 UTF-16 之间是不是存在巨大差异

Posted

技术标签:

【中文标题】UTF-8 和 UTF-16 之间是不是存在巨大差异【英文标题】:Is there a drastic difference between UTF-8 and UTF-16UTF-8 和 UTF-16 之间是否存在巨大差异 【发布时间】:2014-04-19 17:08:42 【问题描述】:

我调用了一个 Web 服务,它返回了一个具有 UTF-8 编码的响应 xml。我在 java 中使用getAllHeaders() 方法检查了这一点。

现在,在我的 java 代码中,我接受该响应,然后对其进行一些处理。然后,将其传递给不同的服务。

现在,我搜索了一下,发现默认情况下,Java 中字符串的编码是 UTF-16。

在我的响应 xml 中,其中一个元素有一个字符 É。现在,这在我向其他服务发出的后处理请求中搞砸了。

它没有发送É,而是发送了一些乱七八糟的东西。现在我想知道,这两种编码真的会有很大的不同吗?如果我想知道 É 会将什么从 UTF-8 转换为 UTF-16,那我该怎么做呢?

【问题讨论】:

如何读写 XML? JAXB?斯塔克斯?你能展示你创建阅读器和作者的代码吗? 【参考方案1】:

有两件事:

交换数据的编码; Java 的内部字符串表示。

您不应该全神贯注于第二点;)问题是使用适当的方法将您的数据(字节数组)转换为Strings(最终是char 数组) ,并将表单Strings 转换为您的数据。

你能想到的最基本的类是CharsetDecoderCharsetEncoder。但还有很多其他的。 String.getBytes()、所有Readers 和Writers 只是两种可能的方法。还有Character的所有静态方法。

如果您在某些时候看到乱码,则表示您未能将原始字节数据解码或编码为 Java 字符串。但同样,Java 字符串使用 UTF-16 的事实与此无关。

特别是,您应该注意,当您创建ReaderWriter 时,您应该指定编码;如果不这样做,将使用默认的 JVM 编码,它可能是也可能不是 UTF-8。

【讨论】:

【参考方案2】:

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

主要的 UTF-8 专业人士:

    基本 ASCII 字符,如数字、拉丁字符,没有 重音等占用一个字节,与 US-ASCII 相同 表示。这样,所有 US-ASCII 字符串都变为有效的 UTF-8, 这在许多情况下提供了不错的向后兼容性。 没有空字节,允许使用以空字符结尾的字符串,这 还引入了大量的向后兼容性。

UTF-8 的主要缺点:

    许多常见字符的长度不同,这会降低索引速度 并且非常计算字符串长度。

主要的 UTF-16 专业人士:

    最合理的字符,如拉丁文、西里尔文、中文、日文 可以用 2 个字节表示。除非真的是异国情调的人物 需要,这意味着 UTF-16 的 16 位子集可以用作 固定长度编码,可加快索引速度。

UTF-16 的主要缺点:

    US-ASCII 字符串中有很多空字节,这意味着没有 以 null 结尾的字符串和大量浪费的内存。

一般来说,UTF-16 通常更适合内存中的表示,而 UTF-8 则非常适合文本文件和网络协议

【讨论】:

很好的回复。你能扼杀我的好奇心,或许还能说出 UTF-32 的实际用途吗?对于我的一生,我想不出它存在的理由。一个简单的 Google 只会让我获得“速度优化”。 我有一个问题,也许是一个非常琐碎的问题。以一个简单的记事本为例。假设我调用了一些服务,它返回了 UTF-8 编码的数据。这基本上是所有 ASCII 或其他一些编码。现在我有一个来自网络服务的角色,即说'A'。现在这个 A 将被映射到 UTF-8 格式的东西。例如 00000000(8 位)。现在,当记事本解释这一点时,它会将其转换为 0000(4 位)。现在,它不会为我搞砸一切吗? 查看我下面的答案 UTF-32 可以说是最易读的 Unicode 编码形式,因为它的大端十六进制表示只是没有“U+”前缀和零填充到八位数字的 Unicode 标量值 嗯.. 也许我不确定我想问的问题。也许我会在稍后的某个时间把它框好,然后在一个单独的线程中提问。【参考方案3】:

本网站提供 UTF TO UTF 转换

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

UTF-32 可以说是 Unicode 编码形式中最易读的,因为它的大端十六进制表示只是没有“U+”前缀和零填充到八位数字的 Unicode 标量值,而 UTF- 32 表示确实使编程模型更加简单,增加的平均存储大小确实存在缺点,使得完全过渡到 UTF-32 的吸引力降低。

但是

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

【讨论】:

【参考方案4】:

UTF-8:一般来说应该使用UTF-8。大多数 html 文档都使用这种编码。

它使用至少 8 位数据来存储每个字符。这可以提高存储效率,尤其是当文本主要包含英文 ASCII 字符时。但是高阶字符,例如非 ASCII 字符,可能每个需要多达 24 位!

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

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

【讨论】:

以上是关于UTF-8 和 UTF-16 之间是不是存在巨大差异的主要内容,如果未能解决你的问题,请参考以下文章

UTF-8 GBK UTF16 GB2312 之间的区别和关系

如何将 xml 返回为 UTF-8 而不是 UTF-16

使用 UTF-8 优于 UTF-16 有啥优势? [复制]

在java中将UTF-16 unicode字符转换为UTF-8

Unicode字符集的UTF-32、UTF-16和UTF-8编码

字符串编码转换