本篇博客学习一下内容
缓冲流概述
BufferedInputStream 字节输入缓冲流
构造方法
BufferedOutputStream 字节输出缓冲流
构造方法
flush() 和 close()
BufferedReader 字符输入缓冲流
构造方法
BufferedWriter 字符输出缓冲流
构造方法
总结
缓冲流是对文件流处理的一种流,它本身并不具备 IO 功能,只是在别的流上加上缓冲提高了效率,当对文件或其他目标频繁读写或操作效率低,效能差。这时使用缓冲流能够更高效的读写信息。因为缓冲流先将数据缓存起来,然后一起写入或读取出来。所以说,缓冲流还是很重要的,在IO操作时记得加上缓冲流提升性能。
BufferedInputStream 和BufferedOutputStream 这两个类分别是InputStream 和OutputStream 的子类,作为装饰器子类,使用它们可以防止每次读取/发送数据时进行实际的写操作,代表着使用缓冲区。
我们有必要知道不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低。带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!
同时正因为它们实现了缓冲功能,所以要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。与之相似还BufferedReader 和BufferedWriter 两个类。
方法 | 功能 |
BufferedInputStream(InputStream in) | 创建 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 |
BufferedInputStream(InputStream in, int size) | 创建具有指定缓冲区大小的 BufferedInputStream,并保存其参数,即输入流 in,以便将来使用。 |
File file1 = new File(path1);
FileInputStream fis = new FileInputStream(file1);
BufferedInputStream bis = new BufferedInputStream(fis);
File file2 = new File(path2);
FileInputStream fis = new FileInputStream(file2);
BufferedInputStream bis = new BufferedInputStream(fis,100);
BufferedInputStream 的 read 方法和 InputStream 的 read 方法一样。它没有重写它父类的 read 方法。
方法 | 功能 |
BufferedOutputStream(OutputStream out) | 创建一个新的缓冲输出流,以将数据写入指定的基础输出流。 |
BufferedOutputStream(OutputStream out, int size) | 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。 |
File file2 = new File(path2);
FileOutputStream fos = new FileOutputStream(file2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
File file1 = new File(path1);
FileOutputStream fos = new FileOutputStream(file1);
BufferedOutputStream bos = new BufferedOutputStream(fos,100);
flush 是从缓冲区把文件写出,
close 是将文件从缓冲区内写出并且关闭相应的流。
缓冲流的数据存储在缓冲区,所以必须强行的将数据从缓冲区写出,否则可能无法写出是数据。
用字节缓冲流来实现文件的拷贝 |
/**
* 类说明
* 描述:TODO
* @author 佳萌
* @date 2018年8月4日
*/
public class TestBuffered {
@Test
public static void copy(String path1,String path2){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//文件
File file1 = new File(path1);
File file2 = new File(path2);
//输入输出文件流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
//输入输出缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len;
//读取数据
while((len = bis.read(b)) != -1){
//写入数据到缓冲区
bos.write(b, 0, len);
//从缓冲区写出数据
bos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bis != null){
try {
//关闭输入流
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null){
try {
//关闭输出流
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
String path1 = "F:\\电影\\厉害了,我的国.2018.HD720P.国语中字.qlv";
String path2 = "F:\\电影\\1.qlv";
copy(path1,path2);
long end = System.currentTimeMillis();
System.out.println(end - start);//708 、
}
}
用同样的方法我们不加缓冲流来做个试验,我们可以看出缓冲流只用了三分之一的时间就完成了同样的工作。
/**
* 类说明
* 描述:TODO
* @author 佳萌
* @date 2018年8月4日
*/
public class TestFileInputStream {
public static void main(String[] args) {
long start = System.currentTimeMillis();
String path1 = "F:\\电影\\厉害了,我的国.2018.HD720P.国语中字.qlv";
String path2 = "F:\\电影\\2.qlv";
copy(path1,path2);
long end = System.currentTimeMillis();
System.out.println(end-start);//2229
}
public static void copy(String path1,String path2){
FileInputStream fis = null;// 文件不存在时会报异常
FileOutputStream fos = null;
try {
fis = new FileInputStream(new File(path1));
fos = new FileOutputStream(new File(path2));
byte[] b = new byte[1024];
int len;
while((len = fis.read(b)) != -1){
fos.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
方法 | 功能 |
BufferedReader(Reader in) | 创建一个使用默认大小输入缓冲区的缓冲字符输入流 |
BufferedReader(Reader in, int sz) | 创建一个使用指定大小输入缓冲区的缓冲字符输入流。 |
@Test
public void test1(){
FileReader reader = null;
try {
//建立流对象
reader = new FileReader("C:\\Users\\Administrator\\Desktop\\file\\file3.txt");
char[] ch = new char[5];
int len;
//读取文件内容
while((len = reader.read(ch)) != -1){
for(int i = 0 ;i < len;i++){
System.out.print(ch[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(reader != null){
try {
//关闭流对象
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
方法 | 功能 |
BufferedWriter(Writer out) | 创建一个使用默认大小输出缓冲区的缓冲字符输出流。 |
BufferedWriter(Writer out, int sz) | 创建一个使用指定大小输出缓冲区的新缓冲字符输出流。 |
@Test
public void test2(){
FileWriter writer = null;
//建立流对象
try {
writer = new FileWriter("C:\\Users\\Administrator\\Desktop\\file\\file3.txt");
String str = " i love china";
char[] ch = str.toCharArray();
writer.write(ch);
} catch (IOException e1) {
e1.printStackTrace();
}finally{
if(writer != null){
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
这是缓冲流的继承关系,所以他们的read和writer方法都是继承自他们的父类,本篇文章就不介绍这些了。