Java Process類小試後感

    前言:雖然沒什麼空,可是也要硬着頭皮更新一下最近遇到的問題。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()的話會出問題的說。部署

相關文章
相關標籤/搜索