开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
缓冲流基本介绍
缓冲流可以提高字节流和字符流的读写数据的性能
缓冲流分为四类:
- BufferedInputStream:字节缓冲输入流,可以提高字节输入流读数据的性能
- BufferedOutStream:字节缓冲输出流,可以提高字节输出流写数据的性能
- BufferedReader:字符缓冲输入流,可以提高字符输入流读数据的性能
- BufferedWriter:字符缓冲输出流,可以提高字符输出流写数据的性能
字节缓冲输入
字节缓冲输入流:BufferedInputStream
作用:可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,提高字节输入流读数据的性能
构造器:public BufferedInputStream(InputStream in)
原理:缓冲字节输入流管道自带了一个 8KB 的缓冲池,每次可以直接借用操作系统的功能最多提取 8KB 的数据到缓冲池中去,以后我们直接从缓冲池读取数据,所以性能较好
public class BufferedInputStreamDemo01 {
public static void main(String[] args) throws Exception {
// 1.定义一个低级的字节输入流与源文件接通
InputStream is = new FileInputStream("Demo/src/test.txt");
// 2.把低级的字节输入流包装成一个高级的缓冲字节输入流。
BufferInputStream bis = new BufferInputStream(is);
// 3.定义一个字节数组按照循环读取。
byte[] buffer = new byte[1024];
int len;
while((len = bis.read(buffer)) != -1){
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}
}
}
字节缓冲输出
字节缓冲输出流:BufferedOutputStream
作用:可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能
构造器:public BufferedOutputStream(OutputStream os)
原理:缓冲字节输出流自带了 8KB 缓冲池,数据就直接写入到缓冲池中去,性能提高了
public class BufferedOutputStreamDemo02 {
public static void main(String[] args) throws Exception {
// 1.写一个原始的字节输出流
OutputStream os = new FileOutputStream("Demo/src/test.txt");
// 2.把低级的字节输出流包装成一个高级的缓冲字节输出流
BufferedOutputStream bos = new BufferedOutputStream(os);
// 3.写数据出去
bos.write('a');
bos.write(100);
bos.write("我爱中国".getBytes());
bos.close();
}
}
字节流性能
利用字节流的复制统计各种写法形式下缓冲流的性能执行情况
复制流:
- 使用低级的字节流按照一个一个字节的形式复制文件
- 使用低级的字节流按照一个一个字节数组的形式复制文件
- 使用高级的缓冲字节流按照一个一个字节的形式复制文件
- 使用高级的缓冲字节流按照一个一个字节数组的形式复制文件
高级的缓冲字节流按照一个一个字节数组的形式复制文件,性能最高,建议使用
字符缓冲输入
字符缓冲输入流:BufferedReader
作用:字符缓冲输入流把字符输入流包装成高级的缓冲字符输入流,可以提高字符输入流读数据的性能。
构造器:public BufferedReader(Reader reader)
原理:缓冲字符输入流默认会有一个 8K 的字符缓冲池,可以提高读字符的性能
按照行读取数据的功能:public String readLine()
读取一行数据返回,读取完毕返回 null
public static void main(String[] args) throws Exception {
// 1.定义一个原始的字符输入流读取源文件
Reader fr = new FileReader("Demo/src/test.txt");
// 2.把低级的字符输入流管道包装成一个高级的缓冲字符输入流管道
BufferedReader br = new BufferedReader(fr);
// 定义一个字符串变量存储每行数据
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
//淘汰数组循环读取
//char[] buffer = new char[1024];
//int len;
//while((len = br.read(buffer)) != -1){
//System.out.println(new String(buffer , 0 , len));
}
字符缓冲输出
符缓冲输出流:BufferedWriter
作用:把低级的字符输出流包装成一个高级的缓冲字符输出流,提高写字符数据的性能。
构造器:public BufferedWriter(Writer writer)
原理:高级的字符缓冲输出流多了一个 8K 的字符缓冲池,写数据性能极大提高了
字符缓冲输出流多了一个换行的特有功能:public void newLine()
新建一行
public static void main(String[] args) throws Exception {
Writer fw = new FileWriter("Demo/src/test.txt",true);//追加
BufferedWriter bw = new BufferedWriter(fw);
bw.write("我爱学习Java");
bw.newLine();//换行
bw.close();
}
高效原因
字符型缓冲流高效的原因:(空间换时间)
- BufferedReader:每次调用 read 方法,只有第一次从磁盘中读取了 8192(8k)个字符,存储到该类型对象的缓冲区数组中,将其中一个返回给调用者,再次调用 read 方法时,就不需要访问磁盘,直接从缓冲区中拿出一个数据即可,提升了效率
- BufferedWriter:每次调用 write 方法,不会直接将字符刷新到文件中,而是存储到字符数组中,等字符数组写满了,才一次性刷新到文件中,减少了和磁盘交互的次数,提升了效率
字节型缓冲流高效的原因:
- BufferedInputStream:在该类型中准备了一个数组,存储字节信息,当外界调用 read() 方法想获取一个字节的时候,该对象从文件中一次性读取了 8192 个字节到数组中,只返回了第一个字节给调用者。将来调用者再次调用 read 方法时,当前对象就不需要再次访问磁盘,只需要从数组中取出一个字节返回给调用者即可,由于读取的是数组,所以速度非常快。当 8192 个字节全都读取完成之后,再需要读取一个字节,就得让该对象到文件中读取下一个 8192 个字节
- BufferedOutputStream:在该类型中准备了一个数组,存储字节信息,当外界调用 write 方法想写出一个字节的时候,该对象直接将这个字节存储到了自己的数组中,而不刷新到文件中。一直到该数组所有 8192 个位置全都占满,该对象才把这个数组中的所有数据一次性写出到目标文件中。如果最后一次循环没有将数组写满,最终在关闭流对象的时候,也会将该数组中的数据刷新到文件中。
注意:字节流和字符流,都是装满时自动写出,或者没满时手动 flush 写出,或 close 时刷新写出