IO流——(5) 字符流——缓冲区——自定义实现缓冲区功能

一、需求:自定义一个缓冲区的功能,实现对文本文件的读取、缓存功能。(模拟BufferedReader)

二、分析:

 缓冲区的功能

 缓冲区的功能,其实就是一个封装了数组的内存区域,提高了io读取的效率。并对外提供了更多的方法对数组进行访问, 其实这些方法最终操作的都是数组的角标。

缓冲区的原理

其实就是从源中读取一批数据装入缓冲区中。在缓冲区中不断的取出一个个数据,在此次取完后,再从源中继续取一批数据进缓冲区。当源中的数据取完时,用-1作为结束标记。

三、具体实现功能:

  需要一个从源数据读取数据到缓冲区中的操作类:FileReader。

   定义一个缓冲区:char [ ] buf = new char[ 1024];

   一个操作缓冲区数组的指针 int pos=0;

    统计缓冲区字符个数的计数器 int count=0;

    读取单个字符到缓冲区的方法  int MyRead( ) {xxx};

   读取一行字符到缓冲区的方法   String MyReadLine( ) { xxx };

 

 四、具体实现代码

1、先实现单个读取方法

/**
*@author James
* @create 2020-01-02 15:07
*
*/


public class MyBufferedReader {


    /**
     * 读取硬盘的字节读取流
     */
    private FileReader r;

    MyBufferedReader(FileReader r){
        this.r=r;
    }


    //定义一个数组作为缓冲区
    private  char[] buf = new char[1024];

    /**
     * 定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归为0
     */
    private  int pos=0;

    /**
     *
     * 定义一个计数器,用于记录缓冲区中的数据个数,当该数据减到0时,就从源中继续获取数据到缓冲区中。
     */

    private  int count=0;

    /**
     * 该方法从缓冲区中一次取一个字符
     * @return
     * @throws IOException
     */
    public int myRead() throws IOException {

    

        if (count==0){
            //从磁盘读取字符到缓冲区
           count= r.read(buf);
            //每次获取数据到缓冲区后,脚标归0
           pos= 0;
        }
        //如果count为负数,就代表缓冲区中数据已读完
        if (count<0){
            return -1;
        }
        
        char ch = buf[pos++];
        count--;
        return ch;
}

2、实现读取一行字符

public class MyBufferedReader {


    /**
     * 读取硬盘的字节读取流
     */
    private FileReader r;

    MyBufferedReader(FileReader r) {
        this.r = r;
    }


    //定义一个数组作为缓冲区
    private char[] buf = new char[1024];

    /**
     * 定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归为0
     */
    private int pos = 0;

    /**
     * 定义一个计数器,用于记录缓冲区中的数据个数,当该数据减到0时,就从源中继续获取数据到缓冲区中。
     */

    private int count = 0;

    /**
     * 该方法从缓冲区中一次取一个字符
     *
     * @return
     * @throws IOException
     */
    public int myRead() throws IOException {

        //从下面逻辑抽取得到
        if (count==0){
            //从磁盘读取字符到缓冲区
           count= r.read(buf);
            //每次获取数据到缓冲区后,脚标归0
           pos= 0;
        }
        //如果count为负数,就代表缓冲区中数据已读完
        if (count<0){
            return -1;
        }

        char ch = buf[pos++];
        count--;
        return ch;
    }

    public String myReadLine() throws IOException {

     StringBuilder sb =new StringBuilder();

     //从缓冲区读到的返回值
     int ch=0;

     while ((ch=myRead())!=-1){
        //将从缓存区读取到的字符,存储到存储一行数据的StringBuild容器中
        if (ch == '\r'){
            continue;
        }

        //遇到换行就直接返回StringBuild中一行字符存入。
        if (ch=='\n'){
            return sb.toString();
        }

        sb.append((char)ch);
     }

        //解决遇到
        if (sb.length()!=0){
            return sb.toString();
        }

        return null;

    }


    public void close() throws IOException {
        r.close();
    }
}

五、测试:将用例中的BuffereadReader( ) 替换成自定义的MyBufferedReader

public class MyBufferedReaderDemo {


    public static void main(String[] args) throws IOException {

        //源文件
        FileReader fr = new FileReader("buf.txt");

        //创建缓冲区 缓冲区中需要装入源文件
        MyBufferedReader bufr = new MyBufferedReader(fr);
        //读一行
        String readLine = null;

        while ((readLine = bufr.myReadLine())!= null) {

            System.out.println(readLine);
        }
        //关闭缓冲区(同时关闭了io流)
        bufr.close();

    }
    

}

结果:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真香号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值