栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK源码-IO系列:缓冲字符流

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK源码-IO系列:缓冲字符流

字符缓冲流

类关系

结合一句代码了解这个类图

BufferedReader bufferedReader = new BufferedReader(new FileReader(inputFile))

new了一个BufferedReader。输入是一个FileReader。
也就是BufferedReader里面的in变量就是FileReader。
另外几个关联的属性:cb,nchars,nextchar等
看看cb的定义:char cb[],BufferedReader是缓冲字符输入流。cb就是字符缓冲区,默认8192长度。作用是存储一次和操作系统io交互之后,读取到的8192个字符数据。
而nchars的含义是当前cb中的字符总数,nextchar是下一个读取的数据的数组下标。

缓冲区读数据算法

当调用bufferedReader.read()时候看下是怎么工作的

缓冲区字符数组取数据的简单算法描述:
1、当第一次读取一个字符的时候,nextchar =0; nchars=0;这是什么含义,这就是说cb字符数组中没有数据,那就调用FileReader读取一组字符数组到cb中。同时修改nchars=8192;返回cb[extchar++]
2、当读取第二个字符的时候,nextchar=1,nchars=8192。那直接返回cb[nextchar];
3、因为nextchar是从0开始的,当读取完字符缓冲去8192个字符后,下一次读取的时候nextchar=8192。这个时候发现nextchar大于等于nchars=8192;就说明已经读取完缓冲区所有数据了。要重新调用FileReader从操作系统文件中读取下一组数据放到字符缓冲区cb中,并且将nextchar设置为0,nchars=8192;
4、不断往复

FileReader.read()

看上面类图FileReader是InputStreamReader的子类,InputStreamReader有属性sd,就是StreamDecoder。
FileReader.read()调用的是InputStreamReader的read()方法,如下,可以看到实际上调用的是StreamDecoder的read方法。

public int read(char cbuf[], int offset, int length) throws IOException {
        return sd.read(cbuf, offset, length);
    }
StreamDecoder原理

StreamDecoder向上,对FileReader提供了读取字符到字符数组的能力。
向下,面向操作系统文件,通过字节流读取字节数据到ByteBuffer类型的bb属性中。

考虑一个事情:
当我们通过ReadableByteChannel ch读取一次数据,这时候,放入bb缓冲区,bb的大小是8192。
而StreamDecoder面向FileReader提供读取字符的能力,假如一次读取8192个字符到字符数组中。

这个时候,因为ByteBuffer bb中有8192个字节。那是不是8192个字节就能转换为8192个字符返回给FileReader呢?
答案是否定的。

字符包括中英文特殊符号等。比如一个中文UTF_8编码,通常使用3或者4个字节编码。

所以bb中的8192个字节,可能转换成3000+个字符。
这个时候bb缓冲区的数据已经解码完了。
需要继续通过ReadableByteChannel ch继续读取字节数据到bb字节缓冲区。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572033.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号