天天看點

Java中使用Process和Runtime()使用詳解

用Java編寫應用時,有時需要在程式中調用另一個現成的可執行程式或系統指令,這時可以通過組合使用Java提供的Runtime類和Process類的方法實作。下面是一種比較典型的程式模式:

  Process process = Runtime.getRuntime().exec("p.exe");

  process.waitfor( );

在上面的程式中,第一行的“p.exe”是要執行的程式名;Runtime.getRuntime()傳回目前應用程式的Runtime對象,該對象的exec()方法訓示Java虛拟機建立一個子程序執行指定的可執行程式,并傳回與該子程序對應的Process對象執行個體。通過Process可以控制該子程序的執行或擷取該子程序的資訊。第二條語句的目的等待子程序完成再往下執行。但在windows平台上,如果處理不當,有時并不能得到預期的結果。下面是筆者在實際程式設計中總結的幾種需要注意的情況:

  1、執行DOS的内部指令如果要執行一條DOS内部指令,有兩種方法。一種方法是把指令解釋器包含在exec()的參數中。例如,執行dir指令,在NT上,可寫成exec ("cmd.exe /c dir"),在windows 95/98下,可寫成“command.exe/c dir”,其中參數“/c”表示指令執行後關閉Dos立即關閉視窗。另一種方法是,把内部指令放在一個批指令my_dir.bat檔案中,在Java程式中寫成exec("my_dir.bat")。如果僅僅寫成exec("dir"),Java虛拟機則會報運作時錯誤。前一種方法要保證程式的可移植性,需要在程式中讀取運作的作業系統平台,以調用不同的指令解釋器。後一種方法則不需要做更多的處理。

   2、打開一個不可執行的檔案打開一個不可執行的檔案,但該檔案存在關聯的應用程式,則可以有兩種方式。以打開一個word文檔a.doc檔案為例,Java中可以有以下兩種寫法:

exec("start a.doc");

exec(" c:\\Program Files\\MicrosoftOffice\\office winword.exe a.doc");

顯然,前一種方法更為簡捷友善。

   3、執行一個有标準輸出的DOS可執行程式在windows 平台上,運作被調用程式的DOS視窗在程式執行完畢後往往并不會自動關閉,進而導緻Java應用程式阻塞在waitfor( )。導緻該現象的一個可能的原因是,該可執行程式的标準輸出比較多,而運作視窗的标準輸出緩沖區不夠大。解決的辦法是,利用Java提供的Process 類提供的方法讓Java虛拟機截獲被調用程式的DOS運作視窗的标準輸出,在waitfor()指令之前讀出視窗的标準輸出緩沖區中的内容。一段典型的程式如下:

String str;

Process process =Runtime.getRuntime().exec("cmd /c dir windows");

BufferedReader bufferedReader = newBufferedReader( new InputStreamReader(process.getInputStream());

while ( (str=bufferedReader.readLine()) !=null) System.out.println(str);  

process.waitfor();

示例

publicstatic booleanresize(String pic,String picTo,int width,int height) {

boolean result = true;

String cmd = "cmd /cconvert -sample " + width + "x" + height + " "" + pic + """ +" "" + picTo+""";

log.debug(cmd);

try {

Process process = Runtime.getRuntime().exec(cmd);

if (process.getErrorStream().read() != -1) {

result = false;

process.destroy();

}

} catch (IOException e) {

log.debug("creat icon pic fail!" + e);

result = false;

}

return result;

}

Sun的doc裡其實說明還有其他的用法:

exec(String[] cmdarray, String[] envp, Filedir)

Executes the specified command andarguments in a separate process with the specified environment and workingdirectory.

那個dir就是調用的程式的工作目錄,這句其實還是很有用的。

Windows下調用程式

Process proc=Runtime.getRuntime().exec("exefile");

Linux下調用程式就要改成下面的格式

Process proc=Runtime.getRuntime().exec("./exefile");

Windows下調用系統指令

String []cmd={"cmd","/C","copy exe1 exe2"};

Process proc=Runtime.getRuntime().exec(cmd);

Linux下調用系統指令就要改成下面的格式

String []cmd={"/bin/sh","-c","ln -s exe1 exe2"};

Process proc=Runtime.getRuntime().exec(cmd);

Windows下調用系統指令并彈出指令行視窗

String []cmd={"cmd","/C","start copy exe1 exe2"};

Process proc=Runtime.getRuntime().exec(cmd);

Linux下調用系統指令并彈出終端視窗就要改成下面的格式

String []cmd={"/bin/sh","-c","xterm -e ln -s exe1 exe2"};

Process proc=Runtime.getRuntime().exec(cmd);

還有要設定調用程式的工作目錄就要

Process proc=Runtime.getRuntime().exec("exeflie",null, newFile("workpath"));

當然最好的執行系統指令的方法就是寫個bat檔案或是shell腳本。然後調用,那樣修改和實作就簡點多了。

還有在在Java程式中截獲控制台輸出[轉]這篇文章中有詳細的如何在JTextArea中顯示攔截的控制台輸出。

首先,大家知道java執行外部指令很簡單,語句如下:

Java代碼

Runtime.getRuntime().exec()

Java代碼

<SPANclass=hilite1>Runtime</SPAN>.<SPANclass=undefined>getRuntime</SPAN>().<SPANclass=hilite3>exec</SPAN>()

這個地球人都知道,但遇到具體問題是要具體分析!ffmpeg是采用指令行的方式進行編譯工作,是以不能直接執行,必須要把指令寫在一個批處理檔案ffmpeg.bat裡,内容如下:

Java代碼

ffmpeg.exe -i %1 -ss 3 -vframes 1 -r 1 -ac1 -ab 2 -s 160*120 -f image2 %2

Java代碼

ffmpeg.exe -i %1 -ss 3 -vframes 1 -r 1 -ac1 -ab 2 -s 160*120 -f image2 %2

%1:接收的參數一

%2:接收的參考二

然後如下:

Java代碼

Runtime.getRuntime().exec("cmd /cstart C:\\ffmpeg.bat " + videoRealPath + " " +imageRealPath)

Java代碼

<SPANclass=hilite1>Runtime</SPAN>.<SPANclass=undefined>getRuntime</SPAN>().<SPANclass=hilite3>exec</SPAN>("cmd/c start C:\\ffmpeg.bat " + videoRealPath + " " +imageRealPath)

由于Runtime.getRuntime().exec不能直接執行批處理檔案,是以要加上"cmd/c start ",至此截圖成功了!

================================================================================================

使用Runtime.getRuntime().exec()方法可以在java程式裡運作外部程式。

1.exec(String command)

2.exec(String command, String envp[], File dir)

3.exec(String cmd, String envp[])

4.exec(String cmdarray[])

5.exec(String cmdarray[], String envp[])

6.exec(String cmdarray[], String envp[], File dir)

一般的應用程式可以直接使用第一版本,當有環境變量傳遞的時候使用後面的版本。其中2和6版本可以傳遞一個目錄,辨別目前目錄,因為有些程式是使用相對目錄的,是以就要使用這個版本。

cmd.exe /c start <FileName>

使用DOS指令(比如dir)時也要使用到調用。如果想與調用的程式進行互動,那麼就要使用該方法的傳回對象Process了,通過Process的getInputStream(),getOutputStream()和getErrorStream()方法可以得到輸入輸出流,然後通過InputStream可以得到程式對控制台的輸出資訊,通過OutputStream可以給程式輸入指令,這樣就達到了程式的交換功能。

用Java編寫應用時,有時需要在程式中調用另一個現成的可執行程式或系統指令,這時可以通過組合使用Java提供的Runtime類和Process類的方法實作。下面是一種比較典型的程式模式:

1

2Process process = Runtime.getRuntime().exec(".\\p.exe");

3process.waitfor();

4

在上面的程式中,第一行的“.\\p.exe”是要執行的程式名,Runtime.getRuntime()傳回目前應用程式的Runtime對象,該對象的exec()方法訓示Java虛拟機建立一個子程序執行指定的可執行程式,并傳回與該子程序對應的Process對象執行個體。通過Process可以控制該子程序的執行或擷取該子程序的資訊。第二條語句的目的等待子程序完成再往下執行。

但在windows平台上,如果處理不當,有時并不能得到預期的結果。下面是筆者在實際程式設計中總結的幾種需要注意的情況:

1、執行DOS的内部指令

如果要執行一條DOS内部指令,有兩種方法。一種方法是把指令解釋器包含在exec()的參數中。例如,執行dir指令,在NT上,可寫成exec("cmd.exe /cdir"),在windows95/98下,可寫成“command.exe /c dir”,其中參數“/c”表示指令執行後關閉DOS立即關閉視窗。另一種方法是,把内部指令放在一個批指令my_dir.bat檔案中,在Java程式中寫成exec("my_dir.bat")。如果僅僅寫成exec("dir"),Java虛拟機則會報運作時錯誤。前一種方法要保證程式的可移植性,需要在程式中讀取運作的作業系統平台,以調用不同的指令解釋器。後一種方法則不需要做更多的處理。

2、打開一個不可執行的檔案

打開一個不可執行的檔案,但該檔案存在關聯的應用程式,則可以有兩種方式。以打開一個word文檔a.doc檔案為例,Java中可以有以下兩種寫法:

1exec("start .\\a.doc");

2exec("Files\\Microsoft Office\\office\\winword.exe .\\a.doc");

顯然,前一種方法更為簡捷友善。

3、執行一個有标準輸出的DOS可執行程式

在Windows平台上,運作被調用程式的DOS視窗在程式執行完畢後往往并不會自動關閉,進而導緻Java應用程式阻塞在waitfor()語句。導緻該現象的一個可能的原因是,該可執行程式的标準輸出比較多,而運作視窗的标準輸出緩沖區不夠大。解決的辦法是,利用Java中Process類提供的方法讓Java虛拟機截獲被調用程式的DOS運作視窗的标準輸出,在waitfor()指令之前讀出視窗的标準輸出緩沖區中的内容。一段典型的程式如下:

1

2String s;

3Process process = Runtime.getRuntime().exec("cmd /c dir\\windows");

4BufferedReader bufferedReader = new BufferedReader(newInputStreamReader(process.getInputStream());

5while((s=bufferedReader.readLine()) != null)

6System.out.println(s);

7process.waitfor();

======================================================================================================================

将pdf文檔轉換為jpg檔案

String com = "java -jard:\\pdfbox-app-1.6.0.jar PDFToImage d:\\jsp.pdf";

Stringstr ="c:\\123.txt";

try{

java.lang.Runtime.getRuntime().exec("cmd/c " + com);

System.out.println(com);

}catch (IOException e) {

//TODO Auto-generated catch block

e.printStackTrace();

}

繼續閱讀