2010-06-16 68 views
21

我正在使用緩衝作者和我的代碼,在finally塊中關閉作者。我的代碼是這樣的。最後使用try catch可以嗎?

........... 
    BufferedWriter theBufferedWriter = null; 
    try{ 
    theBufferedWriter =..... 
    .... 
    ...... 
    ..... 
    } catch (IOException anException) { 
    .... 
    } finally { 
     try { 
      theBufferedWriter.close();    
     } catch (IOException anException) { 
      anException.printStackTrace(); 
      } 
    } 

我不得不在最後的清理代碼中使用try catch,因爲BufferedWriter可能也會拋出一個IOException。我不想把這個異常拋向調用方法。最後使用try catch是否是一種好習慣?如果不是什麼替代方案?請建議。

問候, Hiral

+1

沒關係,但首先檢查null是更好的。 – qrtt1 2010-06-16 07:10:32

+0

+1它不漂亮,但它必須完成 – 2010-06-16 08:38:40

回答

14

一個稍微更好的方式來做到這一點是使用IOUtils.closeQuiety Apache的commons-io。它保持您的代碼整潔,並消除了Java中固有的一些樣板。然後

您的代碼就變成了:

BufferedWriter theBufferedWriter = null; 
try{ 
    theBufferedWriter = ... 
    ... 
} catch (IOException anException) { 
    ... 
} finally { 
    IOUtils.closeQuietly(theBufferedWriter); 
} 

的效果好很多,更傳神。

+3

關閉像這樣緩衝的作家是有風險的;如果字符保留在緩衝區中並且close在嘗試寫入時拋出異常,則數據將被截斷,並且您的應用程序不會處理該錯誤。爲了安全起見,您需要在catch塊之前調用close。 – McDowell 2010-06-16 08:46:12

+2

@McDowell:很高興知道。大概你可以在catch塊之前調用'flush()',對吧? – 2010-06-16 09:09:08

+2

關閉緩衝區將刷新它(請參閱javadoc)。 _如果不清楚,這個模式需要'close'被調用兩次。如果你把_try/finally {close} _移到現有的_try_模塊中,你只需要調用'close'一次2)避免多餘的「空」分配3)不需要導入第三方庫。嵌套的trys看起來很難看,但是通常無法對本地的錯誤處理做出決定,所以catch塊會在調用堆棧中進一步調用。 http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html – McDowell 2010-06-16 12:01:34

11

在前期的Java 7,我說你寫什麼是最好的解決方案。

在Java 7及以後,您有Automatic Resource Management旨在簡化這些事情。有了這個功能,你可以做

BufferedWriter theBufferedWriter = null; 
try (BufferedWriter theBufferedWriter = ...) { 
.... 
...... 
..... 
} catch (IOException anException) { 
.... 
} 
+0

我同意嘗試使用資源是自Java 7以來的最佳方法:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – JavaDev 2016-06-09 09:15:04

2

或者你可以使用Lombok@Cleanup註釋,你永遠不會再寫一個try catch。

這就是你通常會寫(注意throws IOException):

//Vanilly Java 

import java.io.*; 

public class CleanupExample { 
    public static void main(String[] args) throws IOException { 
    InputStream in = new FileInputStream(args[0]); 
    try { 
     OutputStream out = new FileOutputStream(args[1]); 
     try { 
     byte[] b = new byte[10000]; 
     while (true) { 
      int r = in.read(b); 
      if (r == -1) break; 
      out.write(b, 0, r); 
     } 
     } finally { 
     out.close(); 
     } 
    } finally { 
     in.close(); 
    } 
    } 
} 

現在與龍目島,你只是寫@Cleanup在流

import lombok.Cleanup; 
import java.io.*; 

public class CleanupExample { 
    public static void main(String[] args) throws IOException { 
    @Cleanup InputStream in = new FileInputStream(args[0]); 
    @Cleanup OutputStream out = new FileOutputStream(args[1]); 
    byte[] b = new byte[10000]; 
    while (true) { 
     int r = in.read(b); 
     if (r == -1) break; 
     out.write(b, 0, r); 
    } 
    } 
} 
1

這是確定的,但如果theBufferedWriter你應該測試在關閉它之前不是空的。
你也可以這樣做:

BufferedWriter theBufferedWriter; 
try { 
    theBufferedWriter = new ... 
    try { 
     ... 
    } finally { 
     try { 
      theBufferedWriter.close(); 
     } catch (IOException closeException) { 
      closeException.printStackTrace(); 
     } 
    } 
} catch (IOException anException) { 
    ... 
} 

或:

BufferedWriter theBufferedWriter; 
try { 
    theBufferedWriter = new ... 
} catch (IOException createException) { 
    // do something with createException 
    return; // assuming we are in a method returning void 
} 

try { 
    ... 
} catch (IOException anException) { 
    ... 
    // assuming we don't return here 
} 

try { 
    theBufferedWriter.close(); 
} catch (IOException closeException) { 
    closeException.printStackTrace(); 
} 

但主要是我做這樣的操作在一個專用的方法(如寫入文件),喜歡扔/豁免,讓呼叫者可以處理(例如,要求其他文件,停止應用程序,...):

void someMethod(...) throws IOException { 
    BufferedWriter theBufferedWriter = new ... 

    try { 
     ... 
    } catch (IOExcepption anException) { 
     try { 
      theBufferedWriter.close(); 
     } catch (IOException closeException) { 
      closeException.printStackTrace(); 
      // closeException is not thrown, anException represents the main/first problem 
     } 
     throw anException; 
    } 

    theBufferedWriter.close(); // throws the Exception, if any 
} 

請注意:英語不是我的冷杉噸也不是我的第二語言,任何幫助,將不勝感激

0

沒問題,試試抓住最後。它是做你想做的工具。然而,我覺得在關閉時拋出的IOException異常不夠,我會允許它像這樣來抑制體內的任何異常。

try { 
    BufferedWriter writer = ..... 
    try { 
     ..... 
    } finally { 
     writer.close(); 
    } 
} catch (IOException e) { 
    .... 
}