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 的内部字符串表示。您不应该全神贯注于第二点;)问题是使用适当的方法将您的数据(字节数组)转换为String
s(最终是char
数组) ,并将表单String
s 转换为您的数据。
你能想到的最基本的类是CharsetDecoder
和CharsetEncoder
。但还有很多其他的。 String.getBytes()
、所有Reader
s 和Writer
s 只是两种可能的方法。还有Character
的所有静态方法。
如果您在某些时候看到乱码,则表示您未能将原始字节数据解码或编码为 Java 字符串。但同样,Java 字符串使用 UTF-16 的事实与此无关。
特别是,您应该注意,当您创建Reader
或Writer
时,您应该指定编码;如果不这样做,将使用默认的 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 之间的区别和关系
在java中将UTF-16 unicode字符转换为UTF-8