2011-08-17 135 views
19

我在文檔中找不到對此的說明。 但是,當我們有一個Process對象,並調用getInputStream()正確地從getInputStream中關閉Java Process InputStream

,我們會得到我們應該明確地接近,當我們用它做一個新的流? 或 我們是否已經獲得了與流程關聯的流,我們不應該關閉,但流程會關注它嗎?

基本上,我們應該如何與我們從Process.getInputStream()獲得流互動?關閉還是不關閉?

回答

8

我的第一反應是關閉它,你總是關閉你打開的流。我意識到文檔沒有達到標準,但由於他們沒有明確說明請不要關閉對我而言,這意味着遵循良好的編程習慣。

InputStream is = process.getInputStream() 
try { 
    // your code 
} finally { 
    try { is.close(); } catch (Exception ignore) {} 
} 

如果您需要確保這是沒有問題的,只寫了一個快速測試情況下你帶來很大的輸入流中幾十個次,每次打開和關閉的InputStream。

+3

IOUtils.closeQuietly(is)將照顧try {is.close(); } catch(Exception ignore){} – Kirby

5

當您撥打Process.getInputStream()時,您將獲得爲該過程設置的現有輸入流。當進程死亡時,輸入流確實是而非會自動消失 - 將其視爲可以讀取的緩衝區。該進程的管道末端可能會關閉,但您的結束不是。關閉它是你的責任,儘管GC最終會得到它。

您還應該關閉其他兩個:getErrorStream()getOutputStream()

+0

「當進程死亡時,輸入流不會自動消失」 - 當您啓動進程時,Java正在運行「進程收割者」線程,該線程將關閉此類管道的本地端這個案例。 –

0

還是我們獲得與 處理有關的已經存在的數據流,我們不應該關閉,但這個過程會照顧 關閉它?

沒有的Javadoc是這麼說的,是嗎?

2

從閱讀UNIXProcess.java,這是發生了什麼:

我們需要兩個狀態之間進行區分:要麼進程還活着,或者死了。

如果過程是活的,通過關閉的OutputStream(轉到過程的標準輸入),你說的是過程,有沒有爲它更多的投入。通過關閉InputStreams(進程的stdout,stderr),進程不再寫入這些(如果它嘗試,它將得到SIGPIPE)。

當進程終止時,Java將緩衝從標準輸出/標準錯誤剩餘的數據,並關閉所有三個流爲你(正在運行「的過程收割者」線程,這是在過程中死亡通知)。任何嘗試寫入OutputStream都將失敗。從InputStream中讀取將返回緩衝的數據(如果有的話)。關閉他們中的任何一個都沒有好處,但也不會造成傷害。 (底層文件描述符在這個時候關閉)。

0

你不關閉溪流,你沒有打開 - 這是一個討厭的副作用。 如果您創建了該流程,那麼先殺掉它,然後關閉流。