[英]What are the benefits to using a try-finally block for working with an input stream?
這是我在網上找到的Java示例:
try{
//use buffering
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
try{
//deserialize the List
List<String> recoveredQuarks = (List<String>)input.readObject();
//display its data
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
}
finally{
input.close();
}
} catch(ClassNotFoundException ex){
//some exception handling
}
在上面,在關閉輸入之前使用try-finally塊對輸入執行一些處理有什么好處? 換句話說,上面的代碼比這樣的代碼有什么好處:
try{
//use buffering
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
List<String> recoveredQuarks = (List<String>)input.readObject();
for(String quark: recoveredQuarks){
System.out.println("Recovered Quark: " + quark);
}
input.close();
} catch(ClassNotFoundException ex){
//some exception handling
}
有很大的不同:想象以下情況
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
try{
//do sth
throw new RuntimeException();
//do sth else
}
finally{
input.close();
}
在這種情況下,對於finally塊,將引發異常,但將執行finally塊,因此您的輸入將關閉。
如果您的代碼是
InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
//do sth
throw new RuntimeException();
//do sth else
input.close();
您的InputStream無法正確關閉。
但是從Java 7開始,最優雅的版本是使用try-with-resources ,如對您的問題的評論中所述:
try (InputStream file = new FileInputStream ("quarks.ser");
InputStream buffer = new BufferedInputStream (file);
ObjectInput input = new ObjectInputStream (buffer);) {
//do sth
throw new RuntimeException ();
//do sth else
}
使用try / finally ...或更好的try-with-resource的好處是,它在很大程度上防止了以下資源泄漏:
等等。 一般來說,發生這些問題是因為在代碼中存在一些路徑,其中流/套接字/任何東西都不會關閉。 如果使用該路徑的次數過多,則嘗試打開新的流等的嘗試將失敗,因為該應用程序已使用了所有可用的文件描述符。 如果finally
使用正確 ,則可以確保在所有重要情況下都釋放描述符。
還應該指出,您在網上發現的示例是不正確的……至少在理論上是這樣。 如果BufferedInputStream
或ObjectInputStream
的構造函數拋出異常,則將不會執行finally
塊,並且FileInputStream
會泄漏。
更好的編寫方法如下:
try (InputStream file = new FileInputStream("quarks.ser");
InputStream buffer = new BufferedInputStream(file);
ObjectInputStream input = new ObjectInputStream (buffer)) {
// do stuff
} catch (ClassNotFoundException ex){
// handling exception
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.