Problem
使用Properties類別來儲存組態設定是非常方便的事情。在某個知名java教學網站中,在使用Properties建立串流物件上,也有因忘記關閉它而造成Leak。舉例來說:
private void load(){ mProp = new Properties(); try { mProp.load(new FileInputStream(mConfigFilePath)); } catch (IOException e) { // need to handle .. } } public void save(){ try { mProp.store(new FileOutputStream(mConfigFilePath), ""); } catch (IOException e) { // need to handle .. } }
上面程式碼問題就在於FileInputStream與FileOutputStream建構後,沒做close stream的動作。在執行多次後,應會開始出現效能下降或根本無法存取的問題。(可以透過findbug去檢查出來)
How to?
修改方法也相當簡單:
private void close(Closeable closable){ try { if( closable != null ) closable.close(); } catch (IOException e) { // log } } private void load(){ mProp = new Properties(); InputStream is = null; try { is = new FileInputStream(mConfigFilePath); mProp.load(is ); } catch (IOException e) { // need to handle .. } finally { close(is); } } public void save(){ OutputStream os = null; try { os = new FileOutputStream(mConfigFilePath); mProp.store(os, ""); } catch (IOException e) { // need to handle .. } finally { close(os); } }
在使用之前先把它assign到local variable上,在finally的地方在執行close的動作即可,這種錯誤其實蠻多人會犯的。另外對於finally處理關閉串流的方式,許多人會把它寫成nested的try block,多層的try block不只不好閱讀,還可能變無窮的block地獄。對於這部分的處理,大家可以參考搞笑談軟工的幾篇文章: Checked or unchecked exceptions (2)、敏捷式例外處理設計 (4):我到底哪裡做錯之 nested try block、敏捷式例外處理設計 (6):我到底哪裡做錯之 unprotected main program,我相信可以增進不少功力。
留言
張貼留言