1. 程式人生 > >Java中IO流-18-flush和close方法的區別

Java中IO流-18-flush和close方法的區別

    本篇來學習一個小的知識點,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方法的原始碼,發現close方法裡面包含一個flush方法。flush就是重新整理緩衝區的功能,所以,我們可以總結close方法的作用或者特點是:具備重新整理功能,在關閉流之前,就會先重新整理一次快取區,將緩衝區的位元組全都重新整理到檔案上,再關閉流

。這裡,我們來解釋下上面程式碼,沒有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,就會報已經關閉了流,不能再對流進行操作的錯誤。