在浏览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
读取字符的要害代码
<code class="java">// 读取办法,返回单个字符,理论调用上面的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