共计 1138 个字符,预计需要花费 3 分钟才能阅读完成。
在浏览 InputStreamReader
源代码的时候,发现他是一个装璜器模式,所有 read 的办法都依靠到了他的成员变量 StreamDecoder sd
中,在点开 StreamDecoder
源代码发现了其读取逻辑中有个 leftoverChat 的字段,查阅材料发现并没有解释这个字段的文章,回想起以前学习的对于 java 编码的常识,想到这个应该就是 java 的增补编码
首先 java 的 Unicode 编码一共有 1,112,064 字符,然而 Unicode 是 16 位示意,最大示意 65536 个字符,于是只能用两个字符来标识一个字符,把 uD800 到 uDBFF 共 1024 个字符空进去示意 high-surrogates range,把 uDC00 到 uDFFF 共 1024 个字符空进去示意 low-surrogates range,两辆组合就能够示意 1048576,加上 65536-1024-1024 个就能够示意所有的字符
接下来看看StreamDecoder
读取字符的要害代码
// 读取办法,返回单个字符,理论调用上面的 read0()办法
public int read() throws IOException
{return read0();
}
// 返回单个字符
private int read0() throws IOException
{synchronized (lock)
{
// haveLeftoverChar 默认 fasle, 实例域有设置,因而最开始不会进入
if (haveLeftoverChar)
{
haveLeftoverChar = false;
return leftoverChar;
}
// 创立了长度为 2 的字符数组
char cb[] = new char[2];
// 调用上面 read(char cbuf[], int offset, int length)办法,返回读取的字符个数
int n = read(cb, 0, 2);
switch (n)
{
// 若返回 -1. 代表读到开端
case -1:
return -1;
// 读取到 2 个字符,然而办法要求返回一个字符,因而第二个字符就赋予变量临时缓存
case 2:
// 第二个字符赋予变量 leftoverChar
leftoverChar = cb[1];
// 批改条件为真
haveLeftoverChar = true;
// 代表读取到 1 个字符,间接返回数组的第一个元素即可
case 1:
return cb[0];
default:
assert false : n;
return -1;
}
}
}
很简略,当读取到一个字符是便间接返回,读取到两个字符是就是增补编码,先返回 high-surrogates range,下次再返回 low-surrogates range,而 StreamDecoder
中的leftoverChat
就是指 low-surrogates range
正文完