2017-04-04 19 views
-2

我正在運行使用ProcessBuilder的進程。 這是相關代碼:process.waitFor(timeout,timeUnit)不能按預期方式工作

ByteArrayOutputStream resultStream = new ByteArrayOutputStream(); 
ByteArrayOutputStream errorMessage = new ByteArrayOutputStream(); 
ProcessBuilder pb = null; 

pb = new ProcessBuilder("/usr/local/bin/convert", "-limit", "time", "50", "-", "-resize", maxWidth + "x" + maxHeight+">", "-quality", "82","png:-"); 

System.out.println(pb.command()); 
long startTime = System.currentTimeMillis(); 
System.out.println("start time: " + startTime); 
Process process = pb.start(); 
OutputStream stdIn = process.getOutputStream(); 
copy(input, stdIn); 
stdIn.flush(); 
stdIn.close(); 
copy(process.getInputStream(), resultStream); 
copy(process.getErrorStream(), errorMessage); 

boolean exitStatus = process.waitFor(15, TimeUnit.SECONDS); 
if (!exitStatus) { 
      System.out.println("Image processing failed with status " + exitStatus + ": " + errorMessage.toString()); 
} 

     input.close(); 

     System.out.println("returning"); 
     long endTime = System.currentTimeMillis(); 
     System.out.println(endTime); 
     System.out.println("difference :" + (endTime - startTime)*1.0/1000 + " seconds"); 
     return resultStream.toByteArray(); 

的差別是90秒,但我不應該得到關於後15秒失敗的錯誤消息?

注意: 我使用stdin提供輸入到進程,並將輸出和錯誤流作爲字節數組讀取。

+0

我們需要更多的上下文,我建議將[mcve]放在一起,以便人們可以複製問題並幫助您解決問題。 –

+0

StartTime應該設置在waitFor之前的行。使用您當前的代碼,您可能會考慮複製過程花費的時間。 –

+0

您沒有包含「copy」方法的主體,但它看起來像「copy(process.getInputStream(),resultStream);」線將運行直到完成(輸出結束時形成該過程),無論需要多長時間。然後,一旦你到達process.waitFor,那應該立即返回。但是,你仍然在等待copy()命令花費的時間(不過這需要被調用的進程產生輸出)。 – user1676075

回答

2

由於user1676075說,你copy方法運行,直到您的過程結束它的輸出,讓你永遠進程的結束前達到process.waitFor從而達到從未在waitFor返回一個不完整的過程代碼的情況。

+0

謝謝,儘管我提出的問題本來可以用得更好,但這個答案幫助我理解了發生了什麼,並且所有事情都按預期工作。 – gaurav5430

+0

是的,我很抱歉,我從未解決過您的實際問題。您應該將outputStreams以自動刷新模式放入某種數據存儲器(ByteBuffer或取決於預期大小的文件),並等待該過程結束,而不使用阻止複製方法。 –

+1

我最終在單獨的線程中讀取了輸出/錯誤。 waitFor然後按預期工作。 – gaurav5430