一、需求:自定义一个缓冲区的功能,实现对文本文件的读取、缓存功能。(模拟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();
}
}
结果: