一、缓冲区概念:
缓冲区可以简单地理解为一段内存区域。可以简单地把缓冲区理解为一段特殊的内存。某些情况下,如果一个程序频繁地操作一个资源(如文件或数据库),则性能会很低,此时为了提升性能,就可以将一部分数据暂时读入到内存的一块区域之中,以后直接从此区域中读取数据即可,因为读取内存速度会比较快,这样可以提升程序的性能。
举个栗子:去超时购物时,会看到有人提着篮子,和推着购物车,手提篮子很累,推着购物车,取出商品给收银员时又出现重复的工作。一件件的将商品从容器中拿出来,给收银员。这样就很费时间与效率。那么有没有既省力,又效率快的方式呢?其实我们可以将篮子放在购车中,结账时直接将篮子提出来给收银员扫码即可。上述案例中,篮子就充当了缓冲区作用。
作用:缓冲区封装了存放字符的数组,提高了数据在流中的操作效率。
二、形式
以功能名称为开头,结尾为所属体系名称。
例如:
1、写缓冲区:BufferedWriter:
将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。public class BufferedWriter extends Writer
可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途。
提供了一个newLine()方法,它使用平台自己的系统属性line.separator定义的行分隔符概念。 并非所有平台都使用换行符('\ n')来终止行。 因此,调用此方法来终止每个输出行,因此优选直接写入换行符。
一般来说,Writer将其输出立即发送到底层字符或字节流。 除非需要提示输出,否则建议将BufferedWriter包装在其write()操作可能很昂贵的Writer上,例如FileWriters和OutputStreamWriters。 例如,
将缓冲PrintWriter的输出到文件。 没有缓冲,每次调用print()方法都会使字符转换为字节,然后立即写入文件,这可能非常低效。PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
2、读缓存区:BufferedReader:
从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。public class BufferedReader extends Reader
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。
通常,由读取器做出的每个读取请求将引起对底层字符或字节流的相应读取请求。 因此,建议将BufferedReader包装在其read()操作可能昂贵的读取器上,例如FileReaders和InputStreamReaders。 例如,
将缓冲指定文件的输入。 没有缓冲,每次调用read()或readLine()可能会导致从文件中读取字节,转换成字符,然后返回,这可能非常低效。BufferedReader in = new BufferedReader(new FileReader("foo.in"));
使用DataInputStreams进行文本输入的程序可以通过用适当的BufferedReader替换每个DataInputStream进行本地化。
三、演示代码:
1、BufferedWriter
使用FileWriter写法:
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("buf.txt");
fw.write("hdufbhfe");
fw.close();
}
引入缓冲区:
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
//为了提高效率,使用了字符流的缓冲区
//创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象关联
FileWriter fw = new FileWriter("buf.txt");
BufferedWriter bufw = new BufferedWriter(fw);
//使用缓冲区的写入方法将数据先写入到缓冲区
//bufw.write("hubehesdbebf");
//加入换行
//bufw.write("hubhuhj"+LINE_SEPARATOR+"sdbebf");
/* bufw.write("nufrfeihn");
// newLine是属于BufferedWriter的方法,而line.separator是系统底层的。
bufw.newLine();
bufw.write("hufefeje");*/
for (int i=0;i<=4;i++){
bufw.write("acbdha"+i);
bufw.newLine();
bufw.flush();
}
//使用缓冲区的刷新方法将数据刷入目的地
//bufw.flush();
//关闭缓冲区 其实关闭的是底层被缓冲的流对象
bufw.close();
//无需再关闭
// fw.close();
}
2、BufferedReader:
使用FileReader写法代码:
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
char[] buf = new char [1024];
int len = 0;
while ((len =fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fr.close();
}
引入BufferedReader 读缓冲区:
public static void main(String[] args) throws IOException {
//源文件
FileReader fr = new FileReader("buf.txt");
//创建缓冲区 缓冲区中需要装入源文件
BufferedReader bufr = new BufferedReader(fr);
//读一行
String readLine = null;
/**
* 使用BufferedReader的readLine()读一行方法。
*读一行文字。 一行被视为由换行符('\ n'),回车符('\ r')中的任何一个或随后的换行符终止。
*结果:包含行的内容的字符串,不包括任何行终止字符,如果已达到流的末尾,则为null
*/
while ((readLine = bufr.readLine()) != null) {
System.out.println(readLine);
}
//关闭缓冲区(同时关闭了io流)
bufr.close();
}
3、控制台结果:和源文件中buf.txt格式一模一样。
四、readLine:读取一行的原理图解:
五、使用缓存区技术:实现文本文件的复制
先读后写,使用缓存区作为中转站。
public static void main(String[] args) throws IOException {
//源文件
FileReader fr = new FileReader("buf.txt");
BufferedReader bufr = new BufferedReader(fr);
//写入目的地
FileWriter fw = new FileWriter("BuffCopyTest.txt");
BufferedWriter bufw =new BufferedWriter(fw);
/**
* 单个字符读取方式
*/
/*int ch = 0;
while ((ch=bufr.read())!=-1){
fw.write(ch);
}
bufw.close();
bufr.close();
*/
/**
* 读取一行方式 readLine()
*/
String readLin = null;
while ((readLin=bufr.readLine())!=null){
bufw.write(readLin);
//换行
bufw.newLine();
//将数据刷入磁盘(一定要写,不然数据无法存入)
bufw.flush();
}
}
结果: