iT邦幫忙

DAY 20
2

實戰 Java SE 7 系列 第 20

複習 - 關閉資料流

還記得第15天的 範例 嗎?那個範例其實不夠完整!
在那個範例程式裡,我們開啟了在 C 磁碟根目錄下的 temp.txt 檔案(第12行),然後程式讀取一行(第13行)就結束了。我們少做了一件事,那就是把檔案給關閉!雖然程式很短,沒有關閉似乎也不影響什麼,但當你的程式愈寫愈大時,可能會存取某些案上千上萬次,若是忽略了這個小小的動作,輕則造成程式當機,重則保貴的資料毀損,那可就得不嘗失了~

所以好習慣的養成,就是靠著每個小細節,那該怎麼正確地關閉程式中開敵的檔案呢?請看下面這個例子:

package idv.jacky.ironman4;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Day20Example {

	public static void main (String[] args) throws IOException {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader("c:\\temp.txt"));
			String line;
			while ((line = br.readLine()) != null)
				System.out.println(line);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null)
				br.close();
		}

	}
}

上面的例子,我們做得完整一點,程式同樣開啟 C 磁碟根目錄下的 temp.txt 檔案,接著透過一個 while 迴圈,將案的內容一行讀取出來後印出在螢幕上。因為產生 FileReader 物件和 BufferedReader.readLine 方法可能會丟出 IOException,所以我們必需要 catch 這個例外。而關閉檔案的程式碼我們就寫在 final 這個區塊裡,之所以要寫在 final 區塊裡主要的原因是,除了程式突然中斷執行外,在 main 方法結束前,一定會執行 final 區塊裡的程式碼!這樣我們就不怕不會沒有執行到關閉檔案的程式碼。

我們將 BufferedReader 物件變數宣告 try-catch 區塊之前,原因是如果宣告在 try 區塊內的話,在離開 try 區塊之後,這個變數就失效了,那麼 final 區塊就沒辦法使用 br 變數了!在 final 區塊裡,我們得先確認一下 br 變數是不是 null,因為我們在第10行宣告時,並沒有對它做初始化的動作,程式有可能在第12行產生 BufferedReader 變數時出錯,程式會直接跳到第17行執行後,接著執行 final 區塊。如果我們沒有判斷而直接執行第20行程式碼的話,程式將會丟出 NullPointerException。

程式第20行呼叫的 close 方法,就是關閉 BufferedReader 物件資料流的方法,它也會順便幫你把 FileReader 物件資料流給關閉。所有在 java.io 這個 package 下的 Stream 和 Reader 還有 Writer 類別等,都有提供 close 這個方法,讓你來關閉相關的資料流。

這樣就好了嗎?close 方法也會有可能丟出 IOException 例外,所以怎麼辦呢?一種是再 final 區塊裡,再用一個 try-catch 來包住 close 程式碼;或是我們想交給呼叫這個方法的人來處理,那就在方法的宣告上,多宣告這個方法會丟出 IOException 例外(第9行)。這樣整個範例就完整了!


上一篇
Project Coin - 改進泛型實作在創建時的型別推論 完
下一篇
Project Coin - try-with-resource 語法
系列文
實戰 Java SE 7 31

2 則留言

0
timloo
iT邦研究生 2 級 ‧ 2011-11-02 08:28:11

15天的範例的超連結,沒有直接連到那篇文章。

回想到之前金融海嘯的兩年多前,

待業時,路java scjp6的認証,java i/o 是必考的題目,考古題裏,

有一題連環new的考古題,類似new BufferedReader(new FileReader("c:\\temp.txt"));
連續new了好幾個,覺得太神奇,
如:
1。怎麼可以一行寫呢?

2。不一行寫,一行一個new,5個class,就new 5次。也蠻麻煩的,可以促進了解。
一定要new那麼嗎? 最接近的class new不就好了??不過是開個檔案。

3。雖然new很多 instance出來,不用free,因為是gc (垃圾回收也是必考題,但是不易用code來感受)。

4。stream,reader…,不是都源於一個祖先嗎? 所以可以多型,但是多型的考題通常不是考這個。

5。久了沒用,都忘光了,都怪oracle 收購sun之後,到處興訟要錢,覺得java,mysql不太迷人了。為了考試,而用力的try 考古題,才發現,以前對程式語言的了解,通常都是20%,真懷念那段
System.out.println ,把訊息丟出來的方式,200題大多數都println ,就是不知道指令列java 怎麼進入除錯模式,現在還是不知道(慘?!!)那時候練習都是在指令列進行,沒有用eclipse。debug才用eclipse。

0
jackychu
iT邦新手 3 級 ‧ 2011-11-02 23:58:55
  1. Java 算中規中矩了,你看過Python的話,那才叫神奇
    2,4: 開檔的話,的確只要FileReader 或 FileInputStream,但我需要一行一行的讀,所以才又塞給 BufferedReader,然後叫用它的 readLine 方法

我要留言

立即登入留言