簡體   English   中英

使用try-finally塊處理輸入流有什么好處?

[英]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使用正確 ,則可以確保在所有重要情況下都釋放描述符。

還應該指出,您在網上發現的示例是不正確的……至少在理論上是這樣。 如果BufferedInputStreamObjectInputStream的構造函數拋出異常,則將不會執行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM