字符流
缓冲的字符流BufferedReader(缓冲区输入流)/BufferedWriter(缓冲区的输出流):
每次调用read()方法进行操作时,都会直接在文件中读取字节,为了解决这样频繁的读取文件,提高运行效率,所以采用缓冲处理的方式。
缓冲的字符流的出现提高了对流的操作效率,原理就是将数组进行封装。
在使用缓冲的字符流对象时,缓冲的存在是为了增强流的功能,因此在建立缓冲的字符流对象时,要先有流对象的存在。
输入流方法:
public Buffereder(Reader in);
public Buffereder(Reader in,int sz);
输出流方法:
public BufferedWriter(Writer out);
public BufferedWrite(Writer out,int sz);
在缓冲输入流和输出流中都有其特有的方法:
BufferedReader:
public String readLine(); //一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。
BufferedWriter:
BufferedWriter的特有方法:public void newLine();//写出平台相关的行分隔符来标记一行的终止。Windows平台下为’\n’。
注:使用缓冲的字符流时其实就是使用流对象的方法,只不过加入了数组,对数据进行了临时存储,为了提高操作数据的效率。
缓冲字符流的使用:
import java.io.*;
public class BufferDemo {
public static void main(String[] args){
FileWriter fw=null;//建立一个普通的字符输出流
BufferedWriter bw=null;//建立一个缓冲的字符输出流
try {
fw=new FileWriter("res/demo.txt");
bw=new BufferedWriter(fw);//实例化缓冲字符流,括号中的参数以普通字符流作参数
bw.write("hello");
bw.newLine();//在文件中增加一个换行符
bw.write("java");
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
方法readLine()的原理:该方法用的还是与缓冲的字符流相关联的流对象的read()方法,只不过,每一次读到一个字符,先不进行具体操作,先进行临时存储,当读取到回车标记时,将临时容器中存储的数据一次性返回。
自己构造一个类似BufferedReader的类:
package IO;
//构建一个缓冲的输入流(对普通流做一个封装)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class MyBufferedReader {
//属性
private Reader r;//代表普通输入流的输入对象
//构造方法
public MyBufferedReader(Reader r){
this.r=r;
}
//readLine()读一行的方法:增加一个缓冲区,然后调用r对象的read()读取字符放到缓冲区,
//当读到行标记时,把缓冲区中的字符转换成字符串返回
public String readLine(){
//缓冲区
StringBuffer strB=new StringBuffer();
int ch=0;
try {
while((ch=r.read())!=-1){
if(ch=='\n'){
//到这行最后了
return strB.toString();
}if(ch=='\r'){
continue;
}else{
//不是换行符的,就把其放到缓冲区内
strB.append((char)ch);
}
}
} catch (IOException e) {
e.printStackTrace();
}
if(strB.length()!=0){
return new String(strB);
}
return null;
}
//close()方法
public void close(){
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
结论:
在优化增强功能时可以进行装饰设计模式和进行继承子类的方式。但是装饰设计模式比继承有更好的灵活性。
例如在进行Writer的扩展时,当Writer中子类对象过多,那么为了提高每一个对象效率,每一个对象都有 一个自己的子类Buffered。虽然可以实现,但是继承体系变的很臃肿。
而且继承不利于软件的扩展和维护,这样就会发现装饰设计模式,优化增强功能的部分比继承要灵活很多。