2012-12-03 84 views
2

所以。我正在嘗試在Android上做一些網絡內容。在我的異步任務,我做: 在Android中關閉輸入流(Java)

InputStream streamOfDestiny = null; 

try{ 
    // do some network stuff here... 
} 
finally{ 
    if(streamOfDestiny != null){ 
     streamOfDestiny.close(); // Build error here. Apparently, closing a stream can cause an IOException. Why this is the case, I do not know. But it is. And, since this is Java, I apparently need to care. 
    } 
} 

所以,現在我有了這個IOException異常結垢一切。我可以這樣做:

InputStream streamOfDestiny = null; 

try{ 
    // do some network stuff here... 
} 
finally{ 
    if(streamOfDestiny != null){ 
     try{ 
      streamOfDestiny.close(); 
     } 
     catch(IOException e){ 
      // Hey look! I'm inside a catch block, inside a finally block! 
     } 
    } 
} 

但這看起來很糟糕。 finally塊中的try/catch塊?多醜!我可以讓它保持封閉,但這對我來說似乎是不好的練習,只是感覺不對(我開始了這個流,我想完成它)。我可以這樣做:

IOUtils.closeQuietly(streamOfDestiny); 

但現在我必須找到org.apache.commons.io.IOUtils並以某種方式包含了我的包。太多的工作,加上我的包裝大小,我只需要一個功能。瘸。

我總是可以寫我自己的closeQuietly的版本:

public static void closeStreamQuietly(InputStream streamToClose){ 
    try{ 
     streamToClose.close(); 
    } 
    catch (IOException e){ 
     // ignore it.... 
    } 
} 

但只是好像我重新發明輪子,這幾乎總是壞消息 - 感覺,就必須有一些不錯,優雅的做法,我完全不在這裏。

任何想法的人?

回答

0

我不確定你爲什麼要把你的選項-2(try-catch塊內部)或者選項-4(創建一個小的util方法)稱爲醜陋或額外的工作。這是正常的和預期的。

如果您正在finally內編寫任何代碼,則應該完成相關的異常處理,這裏就是這種情況。

通過加入null檢查,您已完成一項異常處理(預防性),否則當streamOfDestiny爲空時,可能會拋出NullPointerException

第二異常處理需要處理的流關閉例外情形中,其可以與所述的原因,如出現流是not openunavailableit's not able to release the underline resources或場景,如this

+0

我不知道 - 也許是我,但是finally塊代表應該總是執行的代碼,try塊是專門處理異常的代碼,導致代碼不被執行。我意識到這並不適用於這種情況,但我仍然不喜歡它。 選項4並不可怕,但我只是期待框架能夠在某個地方處理過這個問題......再次感覺就像重新發明了輪子? 我知道這篇文章的大部分內容都是主觀的 - 也許過於風格化......但是,嘿,我只是想看看我是否錯過了這裏的東西。 – mschultz

+0

@ user1864042這不是重新發明輪子。最後,block是爲了執行你認爲應該運行的那段代碼,即使發生了一些異常。這並不意味着你可以在最後放置任何代碼,Java將自己處理預期的異常。簡而言之,'finally'塊和異常處理是兩個不同的概念。不要混合它們。如果你在finally塊中編寫了一些代碼,相關的異常處理應該明確地完成。無論您是在塊內部執行該操作,編寫自定義方法,使用某個框架還是作爲拋出聲明等,都取決於您。 –

+0

@Yogndra - 我明白了你的觀點....我想這一切都歸結爲我仍然不明白爲什麼close應該拋出異常 - 而且我認爲框架應該提供一種方法來關閉IO流在不拋出任何東西的情況下,一種實現邏輯的方法「我在這裏有這個IOStream對象,我不再希望使用它,請關閉它,讓它停止它做的任何事情,釋放它使用的任何資源(連接等) ,然後讓我繼續我的快樂之路「。 – mschultz

0

沒有神祕感。 close()在大多數實現中調用flush()(請參閱Javadoc的FilterOutputStream),而flush()可能會拋出IOException,,因爲它可能會執行I/O。其他可能性是可以想象的。

0

您應該使用資源嘗試。

try (InputStream streamOfDestiny = ...) { 
    //Do you networking stuff 
} catch (IOException ioe) { 
    //Handle the exceptions 
}