在阅读InputStreamReader的源码时,发现它是一个装饰器模式,所有的read方法都依赖于它的成员变量StreamDecodersd。当我打开StreamDecoder的源码时,发现它的读取逻辑中有一个leftoverChat字段。查了资料,发现没有文章解释这个字段。回想之前学习java编码的知识,我想这应该是java的补充编码。首先,java的Unicode编码一共有1,112,064个字符,但是Unicode是16位表示,最大表示65536个字符,所以只能用两个字符来标识一个字符,一共遗漏了1024个字符从uD800到uDBFF表示high-surrogatesrange,从uDC00到uDFFF一共剩下1024个字符表示low-surrogatesrange,两车组合可以表示1048576,加上65536-1024-1024可以表示所有字符Next,我们看一下StreamDecoder读取字符的关键代码//Read方法,返回单个字符,实际上调用了下面的read0()方法publicintread()throwsIOException{returnread0();}//返回单个字符privateintread0()throwsIOException{synchronized(lock){//haveLeftoverChar默认为fasle,设置了实例字段,所以不会进入if(haveLeftoverChar){haveLeftoverChar=false;返回剩余字符;}//创建了一个字符数组charcb[]=newchar[2];//调用下面的read(charcbuf[],intoffset,intlength)方法,返回读取的字符数intn=read(cb,0,2);开关(n){//如果返回-1。代表读case-1结束:return-1;//读取了2个字符,但是该方法要求返回一个字符,所以第二个字符赋值给临时缓存的变量case2://第二个字符赋值给变量leftoverCharleftoverChar=cb[1];//修改条件为真haveLeftoverChar=true;//表示读取到1个字符,直接返回数组第一个元素case1:returncb[0];默认值:assertfalse:n;返回-1;}}}很简单,读到一个字符就直接返回,读到两个字符就是补充码,先返回high-surrogatesrange,下次再返回low-surrogatesrange,leftoverChat在StreamDecoder指的是低代理范围
