缓冲流
基本介绍
缓冲流可以提高字节流和字符流的读写数据的性能
-
BufferedInputStream 是 Java 编程语言中的一个类,它为输入流提供缓冲。它用于从源(如文件或网络连接)读取数据,并将数据存储在缓冲区中。这可以通过减少所需的单个读取操作的数量来提高输入操作的效率。
-
BufferedOutputStream 是 Java 编程语言中的一个类,它为输出流提供缓冲。它用于将数据写入目的地,例如文件或网络连接,并将数据存储在缓冲区中。这可以通过减少所需的单个写入操作的数量来提高输出操作的效率。
-
BufferedReader 是 Java 编程语言中的一个类,它为读取器流提供缓冲。它用于从源读取文本数据并将数据存储在缓冲区中。可用于提高文本输入操作的效率,支持字符编码方案的使用。
-
BufferedWriter 是 Java 编程语言中的一个类,它为编写器流提供缓冲。它用于将文本数据写入目标并将数据存储在缓冲区中。可用于提高文本输出操作的效率,支持字符编码方案的使用。
总体而言,这些类用于为 Java 中的输入/输出流提供缓冲,提高输入/输出操作的效率,支持文本数据使用字符编码方案。
字节缓冲输入
字节缓冲输入流: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 时刷新写出
转换流
乱码问题
字符流读取:
代码编码 文件编码 中文情况。
UTF-8 UTF-8 不乱码!
GBK GBK 不乱码!
UTF-8 GBK 乱码!
- 如果代码编码和读取的文件编码一致,字符流读取的时候不会乱码
- 如果代码编码和读取的文件编码不一致,字符流读取的时候会乱码
字符输入
字符输入转换流:InputStreamReader
作用:解决字符流读取不同编码的乱码问题,把原始的字节流按照默认的编码或指定的编码转换成字符输入流
构造器:
public InputStreamReader(InputStream is)
:使用当前代码默认编码 UTF-8 转换成字符流public InputStreamReader(InputStream is, String charset)
:指定编码把字节流转换成字符流
public class InputStreamReaderDemo{
public static void main(String[] args) throws Exception {
// 1.提取GBK文件的原始字节流
InputStream is = new FileInputStream("D:\seazean\Netty.txt");
// 2.把原始字节输入流通过转换流,转换成 字符输入转换流InputStreamReader
InputStreamReader isr = new InputStreamReader(is, "GBK");
// 3.包装成缓冲流
BufferedReader br = new BufferedReader(isr);
//循环读取
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
}
}
字符输出
字符输出转换流:OutputStreamWriter
作用:可以指定编码把字节输出流转换成字符输出流,可以指定写出去的字符的编码
构造器:
public OutputStreamWriter(OutputStream os)
:用默认编码 UTF-8 把字节输出流转换成字符输出流public OutputStreamWriter(OutputStream os, String charset)
:指定编码把字节输出流转换成
OutputStream os = new FileOutputStream("/usr/local");
OutputStreamWriter osw = new OutputStreamWriter(os,"GBK");
osw.write("测试i");
osw.close();
本文正在参加「金石计划 . 瓜分6万现金大奖」