本篇来学习一个小的知识点,flush方法和close方法的区别。前面我们介绍了和使用了close方法,知道是用来关闭流的操作,但是并没有介绍flush方法,字面意思的刷新的意思。下面我们来先看看一个例子,然后引出flush方法。

1.如果不关闭流执行代码

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		
	}

}

     执行上面代码,你可以对比copy.war文件的大小和jenkins.war区别,发现copy.war文件会比原文件jenkins.war要小一些。为什么会发生这个情况呢,答案就是在close方法了。在Eclipse中,查看close方法的源码如下:

@SuppressWarnings("try")
    public void close() throws IOException {
        try (OutputStream ostream = out) {
            flush();
        }
    }

具备刷新功能,在关闭流之前,就会先刷新一次缓存区,将缓冲区的字节全都刷新到文件上,再关闭流。这里,我们来解释下上面代码,没有close方法,也就是没有进行刷新操作,文件为什么会变小。文件变小,说明了还有一部分内容没有完成写入到文件。前面一篇,我们介绍了缓冲区默认大小是8192字节,上面文件在最后一次写入到文件的缓冲区里,里面字节数没有8192大小,所以不会触发自动写入操作,从而留下一部分字节没有写入到文件。只要文件不是8192字节的N倍大小,如果最后不进行close操作,肯定会丢失一部分数据。

2.用flush方法代替close方法

为了验证close方法包含flust,我们用flush方法代替close来进行测试下。

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		bos.flush();
	}

}

       如果你继续注销flush方法,还是发现拷贝之后文件变小。这里来总结下flush功能,主要就是刷新的作用,刷新完还可以继续写操作,这个典型的应用可以脑补下QQ即时聊天场景就好。

3.flush和close区别

    简单来说,close包含flush功能,但是flush具备刷新完,还可以继续写操作,close执行完了就流关闭了,不能再写入,所以,不能用close来代替flush。为了证明这个结论,可以执行下面代码。

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4_BufferCopy {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\jenkins.war");
		FileOutputStream fos = new FileOutputStream("copy.war");
		//创建缓冲区,对输入流进行包装
		BufferedInputStream bis = new BufferedInputStream(fis);
		//创建缓冲区,对输出流进行包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		
		int b;
		while ( (b = bis.read()) != -1) {
			bos.write(b);
			bos.flush();
			//bos.close();
		}
		//关闭输入流缓冲区
		//bis.close();
		//关闭输出流缓存区
		//bos.close();
		
	}

}

     我在没一次写入文件操作后,里面执行刷新一次,当然这样写的后果就是拷贝执行过程太慢,耗时。但是如果这里尝试用close方法来代替flush,就会报已经关闭了流,不能再对流进行操作的错误。