缓冲流是对字节流和字符流的一种封装,通过在内存中开辟缓冲区来提高I/O操作的效率,Java 通过BufferedInputStream和BufferedOutputStream来实现字节流的缓冲,通过 BufferedReader 和 BufferedWriter 来实现字符流的缓冲。
缓冲流的工作原理是将数据先写入缓冲区,当缓冲区满时再一次性写入文件或输出流,或者当缓冲区为空时,一次性从文件或输入流读取一定量的数据。这样可以减少I/O操作的次数,提高程序运行的效率。
字节缓冲流
BufferedInputStream
类与其他输入流一起使用,可以更有效地读取数据(以字节为单位)。
它扩展了InputStream
抽象类。
BufferedInputStream
维护 8192 字节的内部缓冲区。内部缓冲区的默认大小为8192字节。我们也可以自定内部缓冲区的大小。
在BufferedInputStream
中进行读取操作期间,将从磁盘读取一部分字节并将其存储在内部缓冲区中。 并从内部缓冲区中逐个读取字节。
BufferedInputStream buffer = new BufferInputStream(file, int size);
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("test.txt"));
BufferOutputStream
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
案例
long startTime = System.currentTimeMillis();
try (FileInputStream fileInputStream = new FileInputStream("a.mp4");
FileOutputStream fileOutputStream = new FileOutputStream("b.mp4")
) {
int tmp;
while ((tmp = fileInputStream.read()) != -1) {
fileOutputStream.write(tmp);
}
}
long endTime = System.currentTimeMillis();
System.out.println("复制时间" + (endTime - startTime) + "ms");
long startTime2 = System.currentTimeMillis();
try (
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("a.mp4"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("c.mp4"))
) {
int tmp;
while ((tmp = bufferedInputStream.read()) != -1) {
bufferedOutputStream.write(tmp);
}
}
long endTime2 = System.currentTimeMillis();
System.out.println("复制时间" + (endTime2 - startTime2) + "ms");
long startTime3 = System.currentTimeMillis();
try (
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("a.mp4"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("c.mp4"))
) {
int tmp;
byte[] bytes = new byte[5 * 1024];
while ((tmp = bufferedInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, tmp);
}
}
long endTime3 = System.currentTimeMillis();
System.out.println("复制时间" + (endTime3 - startTime3) + "ms");
通过上述的三个案例可以明显的发现,使用缓冲流进行文件的读写操作时,速度明显的要快很多,要想速度更快的话,可以通过设置读取的字节数组来调整。
为什么字节缓冲流这么快?
传统的 IO 是阻塞式的,他的工作状态就是读写、等待、读写......,以此循环。
字节缓冲流通过一次多读点多写点,减少读写的频率,从而提高程序执行效率,属于用空间换时间。
减少系统调用次数:在使用字节缓冲流时,数据不是立即写入
字符缓冲流
BufferedReader
BufferedWriter
try (FileInputStream fileInputStream = new FileInputStream("input.txt");
FileOutputStream fileOutputStream = new FileOutputStream("output.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream))
) {
int tmp;
while ((tmp = bufferedReader.read()) != -1) {
bufferedWriter.write(tmp);
}
} catch (IOException e) {
e.printStackTrace();
}