为什么这样说:CharacterStream类用于执行16位Unicode系统的输入/输出?

问题描述

当I / O流管理8位字节的原始二进制数据时,它是 称为字节流。而且,当I / O流管理16位Unicode时 字符,它称为字符流。

Byte stream很清楚。它使用 8位字节。因此,如果我要编写一个使用 3个字节字符,它只会写其最后的 8位!因此输出不正确。

这就是为什么我们使用character streams。假设我想写拉丁大写字母。我需要 3个字节才能存储在UTF-8中。但是说我也想存储'normal'A。现在将需要 1个字节来存储!

您看到图案了吗?在转换它们之前,我们不知道写入这些字符中的任何一个将花费多少字节。所以我的问题是,为什么说character streams manage 16-bit Unicode characters?如果我写的占用了 3个字节,却没有像byte streams那样将其削减为最后16位 > 8位。那句话甚至意味着什么?

解决方法

在Java中,this.getUsers = this.getUsers.bind(this); 由一系列16位String组成,代表以UTF-16编码存储的文本。

char是一个对象,它描述如何将Unicode字符转换为字节序列。 UTF-8是字符集的示例。

Charset这样的字符流在输出到包含字节的东西(文件)或像Writer这样的字节输出流时,会使用OutputStream来转换{ {1}}到简单字节序列进行输出。 (从技术上讲,它会将UTF-16字符转换为Unicode字符,然后使用Charset将其转换为字节序列。)String在从字节源读取时进行反向转换。>

在UTF-16中,Ạ表示为16位Charset Reader。在UTF-16中只需要16位,而在UTF-8中只需要24位。

如果您使用UTF-8编码将其转换为字节,如下所示:

char

然后,您将按预期获得3个字节的序列0xE1 0xBA 0xA1。

,

在Java中,字符(char)始终为16位,从其最大值65535可以看出。这就是为什么引用没有错的原因。 16位确实是一个字符。

“如何将所有Unicode字符仅存储16位?”你可能会问。这是使用Java UTF-16编码完成的。这是它的工作原理(用非常简单的术语表示):

基本多语言平面中的每个Unicode代码点均以16位编码。 (仅16位就足够了)BMP之外的每个代码点都用一对16位字符编码,称为代理对。

“Ạ”(U + 1EA0)在BMP内,因此可以用16位进行编码。

您说:

说我想写拉丁文大写字母Ạ。我需要3个字节才能存储在UTF-8中。但是说我也想存储“普通”A。现在将需要1个字节来存储!

这不会使引用不正确。该流仍然“管理16位字符”,因为这就是您将使用Java代码为其提供的内容。当您在println上调用PrintStream时,您将得到一个String,这是一堆char的表象,是一堆16位。因此,它实际上是在管理16位字符流。只是它以不同的编码输出它们。

可能值得一提的是,当您尝试打印不在BMP中的字符时会发生什么。这仍然不会使报价不正确。引号没有说“代码点”。它说“字符”,它表示您要打印的代理对的上/下代理。