前言:雖然沒什麼空,可是也要硬着頭皮更新一下最近遇到的問題。java
Java項目中須要調用到ffmpeg命令,得知Java的Process類能夠使用。shell
常規的Process類使用網上有不少,貼一個最經典的例子。tomcat
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class ExecShell { public static void main(String args[]) { Process process = null; List<String> processList = new ArrayList<String>(); try { process = Runtime.getRuntime().exec("ps -aux"); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { processList.add(line); } input.close(); try { process.waitFor(); } catch (Throwable e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } for (String line : processList) { System.out.println(line); } } }
這裏Runtime類是單例,從該類調用exec(String)方法能夠得到Process對象。Process對象有三個流對象,對應三個管道:標準輸入流,標準輸出流和錯誤流。標準輸入流和錯誤流實際上是Process類的輸出,標準輸出流則是Java代碼對Process對象的輸入。ide
通常來講是相安無事的,不過當你調用長時間工做的命令時,該命令的輸入流裏將有大量數據寫進緩衝區,若你不取出來,命令將再也不執行,而是阻塞,等待你的取出。這是代碼就沒法繼續運行下去了。ui
當我在jdk7和tomcat6下把三個流都關閉時,shell命令是能夠執行的。code
process.getErrorStream().close(); process.getInputStream().close(); process.getOutputStream().close();
可是,當我部署到jdk8和tomcat7時,以上的代碼使得shell命令不執行,因此我只能一直把輸入流的數據取出來。此次,我使用ProcessBuilder類得到Process對象,把標準輸入流和錯誤流合併,而且一直往輸入流取出數據。因而長時間運行的shell命令得以運行。對象
@Override public String call(String shellString){ Process process = null; try { ProcessBuilder pBuilder = new ProcessBuilder(shellString.split(" ")); pBuilder.redirectErrorStream(true); process = pBuilder.start(); process.getOutputStream().close(); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { //System.out.println(line); } input.close(); System.out.println(shellString); try{ process.waitFor(); }catch(Throwable e){ e.printStackTrace(); } process.destroy(); } catch (IOException e) { e.printStackTrace(); } return " < Finished: " + shellString + " > "; }
最後建議,輸入流的數據仍是取出來吧,close()的話會出問題的說。部署