BufferedReader和BufferedWriter各自带了数组缓冲,但读取方式仍然是使用的FileReader的read()方法。有很多人说带缓冲会减少IO次数,但从读取方式IO次数并不会减少,只是会减少IO频率。缓冲去大小为8k,当调用BufferedReader的read()方法时会从缓冲区中挨个读取一个字符。BufferedReader还带了一个readLine()方法,可以每次读取一行。BufferedReader有一个子类lineNumberReader()可以标记行号,该子类也使用了装饰设计模式。
使用样例:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedDemo {
public static void main(String[] args) throws IOException{
//Demo 1
FileWriter fw = new FileWriter("C:\\Users\\hp\\Desktop\\demo.txt");
BufferedWriter bufw = new BufferedWriter(fw);
bufw.write("666666");
bufw.flush();
bufw.close();
//Demo 2
FileReader fr = new FileReader("C:\\Users\\hp\\Desktop\\demo.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null) {
System.out.println(line);
}
//Demo 3
FileReader fr = new FileReader("C:\\Users\\hp\\Desktop\\demo.txt");
BufferedReader bufr = new BufferedReader(fr);
FileWriter fw = new FileWriter("C:\\Users\\hp\\Desktop\\demo.txt");
BufferedWriter bufw = new BufferedWriter(fw);
}
}
装饰者设计模式:
对一组对象的功能进行增强时,就可以使用装饰设计模式。(BufferedReader)
装饰设计模式与继承的区别:装饰和继承都能实现功能的扩展增强。
Writer(继承)
|——TextWriter用于操作文本
|——BufferedTextWriter加入了缓冲技术的操作文本的对象
|——MediaWirter用于操作媒体
|——BufferedMediaWriter加入了缓冲技术的操作媒体的对象
如果这时又多了一个流对象并想要对其加入缓冲技术,则还要生成子类。这会导致继承体系越来越臃肿不够灵活。
使用装饰设计模式后:
Writer(装饰者)
|——TextWriter用于操作文本
|——MediaWirter用于操作媒体
|——BufferedWriter加入了缓冲技术的对象
装饰模式特点:
装饰类和被装饰类必须同属一个借口或者父类,因为修饰后的功能不变(乞丐霸主和乞丐都是得乞讨)。对已有对象进行功能增强使用装饰模式更合适。装饰模式比继承更灵活。
下面是根据源码制造的太监版MyBufferedReader:
import java.io.IOException;
import java.io.Reader;
public class MyBufferedReader extends Reader{ //MyBufferedReader本质也是一种写操作,需要继承
private Reader r;
private char[] buffer = new char[1024]; //缓冲区
private int pos = 0; 当前下标
private int cnt = 0; //缓冲区个数
MyBufferedReader(Reader r){ //使用多态包装更多的Reader子类
this.r = r;
}
public int myRead() throws IOException {
if(cnt == 0) {
cnt = r.read(buffer);
pos = 0;
}
if(cnt < 0)
return -1;
char ch = buffer[pos++];
cnt--;
return ch;
}
public String myReadLine() throws IOException {
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch = myRead()) != -1) {
if(ch == '\r')
continue;
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();
}
@Override
public int read(char[] arg0, int arg1, int arg2) throws IOException {
// TODO Auto-generated method stub
return 0;
}
}