缓冲流是一个包装流,目的起缓冲作用.
1. 缓冲流的作用
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。
带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
2. 缓冲流的分类
- 字符缓冲流:BufferedReader和BufferedWriter
- 字节缓冲流:BufferedInputStream和BufferedOutputStream
BufferedInputStream和BufferedOutputStream这两个类分别是FilterInputStream和FilterOutputStream的子类。作为装饰器子类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
2.1 BufferedInputStream
-
BufferedInputStream 的作用是为另一个输入流添加一些功能,即缓冲输入、支持mark和reset方法的功能。
-
当创建BufferedInputStream时,将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次填充多个字节。
-
mark操作会记住输入流中的一点。
-
reset操作会导致从最近的mark操作之后读取的所有字节在从包含的输入流中取出新的字节之前重新读取。
构造函数
BufferedInputStream(InputStream in)
创建一个BufferedInputStream并保存其参数,输入流in供以后使用。 内部缓冲区数组创建并存储在buf 。
BufferedInputStream(InputStream in, int size)
创建指定缓冲区大小的BufferedInputStream。长度为size的内部缓冲区阵列被创建并存储在buf。
重要方法
-
int available(); 返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
-
int read(); 读取buf中下一个字节
-
int read(byte[] b, int off, int len); 从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。
-
void close(); 关闭此输入流并释放与流相关联的任何系统资源
-
boolean markSupport(); 测试此输入流是否支持mark和reset方法
-
void mark(int readLimit); 标记此输入流中的当前位置。 对reset方法的后续调用会将该流重新定位在最后一个标记的位置,以便后续重新读取相同的字节。
-
void reset(); 将此流重新定位到上次在此输入流上调用mark方法时的位置。
-
long skip(long n); 跳过n个字节,不仅仅是buf中的有效字节、也包括in的源中的字节
读取文件示例:
//输入文件路径
File file = new File("E:\\demo\\study.txt");
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
int temp = 0;
byte[] data = new byte[1024];
while((temp = buf.read(data)) != -1){
System.out.println(new String(data));
}
buf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.2 BufferedOutputStream
该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。
构造函数
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
重要方法
-
public void write(int b); 将指定的字节写入缓冲的输出流。
-
public void write(byte[] b,int off,int len)
将指定的字节数组从偏移off开始写入len个字节到缓冲的输出流。 -
public void flush() 刷新缓冲输出流。 这将强制任何缓冲输出字节写入底层输出流。
输出到文件示例:
//输出文件路径
File file = new File("E:\\demo\\test.txt");
try {
//使用字节缓冲输出流
BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream(file));
String str = "好好学习,天天向上";
buf.write(str.getBytes());
//关闭流
buf.close();
} catch (Exception e) {
e.printStackTrace();
}
2.3 BufferedReader
BufferedReader是Reader的子类,从字符输入流中读取文本,缓冲字符,以便有效读取字符,数组和行。 可以指定缓冲区大小,也可以使用默认大小。
构造方法
- BufferedReader(Reader in)
创建使用默认大小的输入缓冲区的缓冲字符输入流。
- BufferedReader(Reader in, int sz)
创建使用指定大小的输入缓冲区的缓冲字符输入流。
重要方法
-
public int read() 读一个字符
-
public int read(char[] cbuf,int off,int len) 将字符读入数组的一部分
-
public String readLine() 读一行文字。 一行被认为由换行符(’\ n’),回车符(’\ r’)或回车后立即换行符中的任何一个终止。。(此方法最常用)
-
public Stream lines() 回一个Stream ,其元素是从这个BufferedReader读取的行。
-
public void close() 关闭流并释放与之相关联的任何系统资源
-
public void mark(int readAheadLimit) 标记流中的当前位置
-
public void reset() 将流重置为最近的标记。
-
public boolean markSupported() 告诉这个流是否支持mark()操作。
-
public boolean ready() 告诉这个流是否准备好被读取。 如果缓冲区不为空,或者底层字符流准备就绪,则缓冲字符流就绪。
-
public long skip(long n) 跳过字符
使用BufferedReader读取文件示例:
/**
* 使用BufferedReader读取文件
*/
public static void readFile(){
File file = new File("E:\\demo\\study.txt");
try {
//使用字符缓冲输入流读取文件
BufferedReader buf = new BufferedReader(new FileReader(file));
String str = null;
//每次读取一行
while((str = buf.readLine()) != null){
System.out.println(str);
}
//关闭流
buf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.4 BufferedWriter
BufferedWriter是Writer的子类,将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途。
构造方法
- BufferedWriter(Writer out)
创建使用默认大小的输出缓冲区的缓冲字符输出流。
- BufferedWriter(Writer out, int sz)
创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。
重要方法
-
public void write(int c) 写一个字符
-
public void write(char[] cbuf,int off,int len) 写入字符数组的一部分。
-
public void write(String s,int off,int len) 写一个字符串的一部分。
-
public void newLine() 写入一行
-
public void flush() 刷新流
-
public void close() 关闭流,先刷新。
使用BufferedWriter输出到文件示例:
File file = new File("E:\\demo\\buffer.txt");
try {
BufferedWriter out = new BufferedWriter(new FileWriter(file));
String str = "好好学习,天天向上!!!";
out.write(str);
out.close();
} catch (IOException e) {
e.printStackTrace();
}