为什么说:characterstream类用于为16位unicode系统执行输入/输出?

ercv8c1e  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(325)

当i/o流管理8位字节的原始二进制数据时,它被称为字节流。而且,当i/o流管理16位unicode字符时,它被称为字符流。 Byte stream 很清楚。它使用8位字节。所以如果我要写一个使用3字节的字符,它只会写最后8位!从而产生不正确的输出。
所以我们用 character streams . 说我想写拉丁文大写字母 . 我需要3个字节来存储在utf-8中。但如果我也想储存“正常” A . 现在需要1个字节来存储!
你看到模式了吗?在转换这些字符之前,我们不知道写这些字符需要多少字节。所以我的问题是为什么会这么说 character streams manage 16-bit Unicode characters ? 万一我写了什么 这需要3个字节,它没有像这样把它压缩到最后16位 byte streams 切最后8位。那句话是什么意思?

rn0zuynd

rn0zuynd1#

在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代码提供的。当你打电话的时候 printlnPrintStream ,你在给它一个 String ,这是一堆 char 它在引擎盖下,是一堆16比特。所以它实际上是在管理一个16位字符流。只是它以不同的编码输出它们。
可能值得一提的是,当您尝试打印bmp中没有的字符时会发生什么。这仍然不会使报价不正确。引用没有说“代码点”。它表示“character”,它将引用您正在打印的代理项对的上/下代理项。

gc0ot86w

gc0ot86w2#

在java中,一个 String 由16位的序列组成 char s、 表示存储在utf-16编码中的文本。
Charset 描述如何将unicode字符转换为字节序列的对象。utf-8是字符集的一个例子。
像这样的字符流 Writer ,当它输出到一个包含字节的东西时--一个文件,或者一个字节输出流,比如 OutputStream --使用 Charset 转换 String s到简单的字节序列输出(从技术上讲,它将utf-16字符转换为unicode字符,然后使用 Charset )a Reader ,从字节源读取时,执行反向转换。
在utf-16中,ạ 表示为16位
char 0x1EA1 . 在utf-16中它只需要16位,而不像在utf-8中需要24位。
如果使用utf-8编码将其转换为字节,如下所示:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(baos, StandardCharsets.UTF_8);
writer.write("Ạ");
writer.close();
return baos.toByteArray();

然后您将得到3字节序列0xe10xba0xa1。

相关问题