這個問題是關於java.lang.Process
及其對stdin,stdout和stderr的處理。如何關閉來自java.lang.Process的std-streams?
我們在我們的項目中有一個班級,是org.apache.commons.io.IOUtils
的擴展。在那裏,我們有一個安靜的新方法來關閉Process-Object的std-streams適當的?還是不適合?
/**
* Method closes all underlying streams from the given Process object.
* If Exit-Code is not equal to 0 then Process will be destroyed after
* closing the streams.
*
* It is guaranteed that everything possible is done to release resources
* even when Throwables are thrown in between.
*
* In case of occurances of multiple Throwables then the first occured
* Throwable will be thrown as Error, RuntimeException or (masked) IOException.
*
* The method is null-safe.
*/
public static void close(@Nullable Process process) throws IOException {
if(process == null) {
return;
}
Throwable t = null;
try {
close(process.getOutputStream());
}
catch(Throwable e) {
t = e;
}
try{
close(process.getInputStream());
}
catch(Throwable e) {
t = (t == null) ? e : t;
}
try{
close(process.getErrorStream());
}
catch (Throwable e) {
t = (t == null) ? e : t;
}
try{
try {
if(process.waitFor() != 0){
process.destroy();
}
}
catch(InterruptedException e) {
t = (t == null) ? e : t;
process.destroy();
}
}
catch (Throwable e) {
t = (t == null) ? e : t;
}
if(t != null) {
if(t instanceof Error) {
throw (Error) t;
}
if(t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw t instanceof IOException ? (IOException) t : new IOException(t);
}
}
public static void closeQuietly(@Nullable Logger log, @Nullable Process process) {
try {
close(process);
}
catch (Exception e) {
//log if Logger provided, otherwise discard
logError(log, "Fehler beim Schließen des Process-Objekts (inkl. underlying streams)!", e);
}
}
public static void close(@Nullable Closeable closeable) throws IOException {
if(closeable != null) {
closeable.close();
}
}
方法等這些在最後塊基本上使用。
我真的很想知道的是,如果我在這個實現中安全嗎?考慮如下事情:過程對象是否在其生命週期中始終返回相同的stdin,stdout和stderr流?或者我可能會錯過之前由過程'getInputStream()
,getOutputStream()
和getErrorStream()
方法返回的流?
有上StackOverflow.com一個相關的問題:java: closing subprocess std streams?
編輯
正如指出的我和其他人在這裏:
- InputStreams必須完全消耗掉。未完成時,子進程可能無法終止,因爲其輸出流中有未完成的數據。
- 所有三個標準流都必須關閉。無論之前是否使用過。
- 當子進程正常終止時,一切都應該沒問題。當不是那麼它必須被強行終止。
- 當子程序返回退出代碼時,我們不需要
destroy()
它。它已經終止。 (即使不一定以正常終止代碼0終止,但終止。) - 我們需要監視
waitFor()
並在超時超時時中斷,以使進程有機會正常終止但在掛起時將其終止。
未答覆的部分:
- 考慮優點和並聯消耗InputStreams的缺點。或者必須按特定順序消費?
只是一個說明。你的代碼中有一些嚴重的反模式。 1.嘗試/捕捉幾乎每一條語句。 2.每次抓住一切「可扔」。 3.嵌套的try語句也可以是一個,有兩個catch語句。 –
如何在不將其放入單獨的try-catch塊時關閉其他流? –
由於Throwable可能發生在嵌套的catch-block中,因此必須嵌套try-catch-block。對於捕捉'Throwable':什麼更合適?我想抓住一切值得我努力工作的方式來做最好的關閉資源。之前捕獲時我會拋出一個Throwables。我能在這裏做些什麼? –