1. 如何在java中執行其它程序
在編寫Java程序時,有時候需要在Java程序中執行另外一個程序。
1、啟動程序Java提供了兩種方法用來啟動其它程序:
(1)使用Runtime的exec()方法
(2)使用ProcessBuilder的start()方法
不管在哪種操作系統下,程序具有基本類似的一些屬性。一個程序啟動後就程序操作系統的一個進程,進程在執行的時候有自己的環境變數、有自己的工作目錄。Runtime和ProcessBuilder提供了不同的方式來啟動程序,設置啟動參數、環境變數和工作目錄。
能夠在Java中執行的外部程序,必須是一個實際存在的可執行文件,對於shell下的內嵌命令是不能直接執行的。
採用Runtime的exec執行程序時,首先要使用Runtime的靜態方法得到一個Runtime,然後調用Runtime的exec方
法。可以將要執行的外部程序和啟動參數、環境變數、工作目錄作為參數傳遞給exec方法,該方法執行後返回一個Process代表所執行的程序。
Runtime有六個exec方法,其中兩個的定義為:
public Process exec(String[] cmdarray, String[] envp, File dir)
public Process exec(String command, String[] envp, File dir)
cmdarray和command為要執行的命令,可以將命令和參數作為一個字元串command傳遞給exec()方法,也可以將命令和參數一個一個的方在數組cmdarray里傳遞給exec()方法。
envp為環境變數,以name=value的形式放在數組中。dir為工作目錄。
可以不要dir參數,或者不要envp和dir參數,這樣就多出了其它4個exec()方法。如果沒有dir參數或者為null,那麼新啟動的
進程就繼承當前java進程的工作目錄。如果沒有envp參數或者為null,那麼新啟動的進程就繼承當前java進程的環境變數。
也可以使用ProcessBuilder類啟動一個新的程序,該類是後來添加到JDK中的,而且被推薦使用。通過構造函數設置要執行的命令以及
參數,或者也可以通過command()方法獲取命令信息後在進行設置。通過directory(File directory)
方法設置工作目錄,通過environment()獲取環境變數信息來修改環境變數。
在使用ProcessBuilder構造函數創建一個新實例,設置環境變數、工作目錄後,可以通過start()方法來啟動新程序,與Runtime的exec()方法一樣,該方法返回一個Process對象代表啟動的程序。
ProcessBuilder與Runtime.exec()方法的不同在於ProcessBuilder提供了
redirectErrorStream(boolean redirectErrorStream)
方法,該方法用來將進程的錯誤輸出重定向到標准輸出里。即可以將錯誤輸出都將與標准輸出合並。
2、Process
不管通過那種方法啟動進程後,都會返回一個Process類的實例代表啟動的進程,該實例可用來控制進程並獲得相關信息。Process 類提供了執行從進程輸入、執行輸出到進程、等待進程完成、檢查進程的退出狀態以及銷毀(殺掉)進程的方法:
(1) void destroy()
殺掉子進程。
一般情況下,該方法並不能殺掉已經啟動的進程,不用為好。
(2) int exitValue()
返回子進程的出口值。
只有啟動的進程執行完成、或者由於異常退出後,exitValue()方法才會有正常的返回值,否則拋出異常。
(3)InputStream getErrorStream()
獲取子進程的錯誤流。
如果錯誤輸出被重定向,則不能從該流中讀取錯誤輸出。
(4)InputStream getInputStream()
獲取子進程的輸入流。
可以從該流中讀取進程的標准輸出。
(5)OutputStream getOutputStream()
獲取子進程的輸出流。
寫入到該流中的數據作為進程的標准輸入。
(6) int waitFor()
導致當前線程等待,如有必要,一直要等到由該 Process 對象表示的進程已經終止。
通過該類提供的方法,可以實現與啟動的進程之間通信,達到交互的目的。
3、從標准輸出和錯誤輸出流讀取信息
從啟動其他程序的Java進程看,已啟動的其他程序輸出就是一個普通的輸入流,可以通過getInputStream()和getErrorStream來獲取。
對於一般輸出文本的進程來說,可以將InputStream封裝成BufferedReader,然後就可以一行一行的對進程的標准輸出進行處理。
4、舉例
(1)Runtime.exec()import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
public class Test1 {
public static void main(String[] args) {
try {
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
p = Runtime.getRuntime().exec("CMD.exe /C dir", null, new File("C:\\"));
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
//echo the value of NAME
p = Runtime.getRuntime().exec("CMD.exe /C echo %NAME%", new String[] {"NAME=TEST"});
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
(2)ProcessBuilderimport java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
p = pb.start();
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
//echo the value of NAME
pb = new ProcessBuilder();
mand(new String[] {"CMD.exe", "/C", "echo %NAME%"});
pb.environment().put("NAME", "TEST");
p = pb.start();
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、獲取進程的返回值
通常,一個程序/進程在執行結束後會向操作系統返回一個整數值,0一般代表執行成功,非0表示執行出現問題。有兩種方式可以用來獲取進程的返回
值。一是利用waitFor(),該方法是阻塞的,執導進程執行完成後再返回。該方法返回一個代表進程返回值的整數值。另一個方法是調用
exitValue()方法,該方法是非阻塞的,調用立即返回。但是如果進程沒有執行完成,則拋出異常。
6、阻塞的問題
由Process代表的進程在某些平台上有時候並不能很好的工作,特別是在對代表進程的標准輸入流、輸出流和錯誤輸出進行操作時,如果使用不慎,有可能導致進程阻塞,甚至死鎖。
如果將以上事例中的從標准輸出重讀取信息的語句修改為從錯誤輸出流中讀取:stdout = new BufferedReader(new InputStreamReader(p
.getErrorStream()));
那麼程序將發生阻塞,不能執行完成,而是hang在那裡。
當進程啟動後,就會打開標准輸出流和錯誤輸出流准備輸出,當進程結束時,就會關閉他們。在以上例子中,錯誤輸出流沒有數據要輸出,標准輸出流中
有數據輸出。由於標准輸出流中的數據沒有被讀取,進程就不會結束,錯誤輸出流也就不會被關閉,因此在調用readLine()方法時,整個程序就會被阻
塞。為了解決這個問題,可以根據輸出的實際先後,先讀取標准輸出流,然後讀取錯誤輸出流。
但是,很多時候不能很明確的知道輸出的先後,特別是要操作標准輸入的時候,情況就會更為復雜。這時候可以採用線程來對標准輸出、錯誤輸出和標准輸入進行分別處理,根據他們之間在業務邏輯上的關系決定讀取那個流或者寫入數據。
針對標准輸出流和錯誤輸出流所造成的問題,可以使用ProcessBuilder的redirectErrorStream()方法將他們合二為一,這時候只要讀取標准輸出的數據就可以了。
當在程序中使用Process的waitFor()方法時,特別是在讀取之前調用waitFor()方法時,也有可能造成阻塞。可以用線程的方法來解決這個問題,也可以在讀取數據後,調用waitFor()方法等待程序結束。
總之,解決阻塞的方法應該有兩種:
(1)使用ProcessBuilder類,利用redirectErrorStream方法將標准輸出流和錯誤輸出流合二為一,在用start()方法啟動進程後,先從標准輸出中讀取數據,然後調用waitFor()方法等待進程結束。
如:import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
//merge the error output with the standard output
pb.redirectErrorStream(true);
p = pb.start();
//read the standard output
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
int ret = p.waitFor();
System.out.println("the return code is " + ret);
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
(2)使用線程import java.util.*;
import java.io.*;
class StreamWatch extends Thread {
InputStream is;
String type;
List output = new ArrayList();
boolean debug = false;
StreamWatch(InputStream is, String type) {
this(is, type, false);
}
StreamWatch(InputStream is, String type, boolean debug) {
this.is = is;
this.type = type;
this.debug = debug;
}
public void run() {
try {
PrintWriter pw = null;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
output.add(line);
if (debug)
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public List getOutput() {
return output;
}
}
public class Test5 {
public static void main(String args[]) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
// list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
p = pb.start();
// process error and output message
StreamWatch errorWatch = new StreamWatch(p.getErrorStream(),
"ERROR");
StreamWatch outputWatch = new StreamWatch(p.getInputStream(),
"OUTPUT");
// start to watch
errorWatch.start();
outputWatch.start();
//wait for exit
int exitVal = p.waitFor();
//print the content from ERROR and OUTPUT
System.out.println("ERROR: " + errorWatch.getOutput());
System.out.println("OUTPUT: " + outputWatch.getOutput());
System.out.println("the return code is " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
7、在Java中執行Java程序
執行一個Java程序的關鍵在於:
(1)知道JAVA虛擬機的位置,即java.exe或者java的路徑
(2)知道要執行的java程序的位置
(3)知道該程序所依賴的其他類的位置
舉一個例子,一目瞭然。
(1)待執行的Java類public class MyTest {
public static void main(String[] args) {
System.out.println("OUTPUT one");
System.out.println("OUTPUT two");
System.err.println("ERROR 1");
System.err.println("ERROR 2");
for(int i = 0; i < args.length; i++)
{
System.out.printf("args[%d] = %s.", i, args[i]);
}
}
}
(2)執行該類的程序
import java.util.*;
import java.io.*;
class StreamWatch extends Thread {
InputStream is;
String type;
List output = new ArrayList();
boolean debug = false;
StreamWatch(InputStream is, String type) {
this(is, type, false);
}
StreamWatch(InputStream is, String type, boolean debug) {
this.is = is;
this.type = type;
this.debug = debug;
}
public void run() {
try {
PrintWriter pw = null;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
output.add(line);
if (debug)
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public List getOutput() {
return output;
}
}
public class Test6 {
public static void main(String args[]) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");
// list the files and directorys under C:\
list.add(java);
list.add("-classpath");
list.add(classpath);
list.add(MyTest.class.getName());
list.add("hello");
list.add("world");
list.add("good better best");
pb = new ProcessBuilder(list);
p = pb.start();
System.out.println(mand());
// process error and output message
StreamWatch errorWatch = new StreamWatch(p.getErrorStream(),
"ERROR");
StreamWatch outputWatch = new StreamWatch(p.getInputStream(),
"OUTPUT");
// start to watch
errorWatch.start();
outputWatch.start();
//wait for exit
int exitVal = p.waitFor();
//print the content from ERROR and OUTPUT
System.out.println("ERROR: " + errorWatch.getOutput());
System.out.println("OUTPUT: " + outputWatch.getOutput());
System.out.println("the return code is " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
2. java 怎麼調用windows外部命令
可以使用Java Process類,下面是一些例子:
Process類是一個抽象類,方法都是抽象的,它封裝了一個進程,也就是一個可執行的程序該類提供進程的輸入、執行輸出到進程、等待進程的完成和檢查進程的退出狀態及銷毀進程的方法
ProcessBuilder.start()和Runtime.exec方法創建一個本機進程並返回Process子類的一個實例,該實例可以控制進程並獲取相關的信息
其它的概要請參考JDK文檔
下面就開始舉幾個簡單的示例:
(1)執行簡單的DOS命令,如打開一個記事本
Java代碼
packagecom.iwtxokhtd.other;
importjava.io.IOException;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
try{
Processproc=Runtime.getRuntime().exec("notepad");
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
[java]viewplain
packagecom.iwtxokhtd.other;
importjava.io.IOException;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
try{
Processproc=Runtime.getRuntime().exec("notepad");
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
(2)使用它的其它構造方法執行相關的命令,如下例:
Java代碼
packagecom.iwtxokhtd.other;
importjava.io.IOException;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
try{
StringexeFullPathName="C:/ProgramFiles/InternetExplorer/IEXPLORE.EXE";
Stringmessage="www.google.com";
String[]cmd={exeFullPathName,message};
Processproc=Runtime.getRuntime().exec(cmd);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
[java]viewplain
packagecom.iwtxokhtd.other;
importjava.io.IOException;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
try{
StringexeFullPathName="C:/ProgramFiles/InternetExplorer/IEXPLORE.EXE";
Stringmessage="www.google.com";
String[]cmd={exeFullPathName,message};
Processproc=Runtime.getRuntime().exec(cmd);
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
執行上述命令可以打開Google網站
(3)列出系統正在運行的所有進程信息
Java代碼
packagecom.iwtxokhtd.other;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
publicclassListAllProcessTest{
//列出所有的進程信息
publicstaticvoidmain(String[]args){
BufferedReaderbr=null;
try{
Processproc=Runtime.getRuntime().exec("tasklist");
br=newBufferedReader(newInputStreamReader(proc.getInputStream()));
@SuppressWarnings("unused")
Stringline=null;
System.out.println("列印所有正在運行的進程信息");
while((line=br.readLine())!=null){
System.out.println(br.readLine());
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(br!=null){
try{
br.close();
}catch(Exceptione){
e.printStackTrace();
}
}
}
}
}
[java]viewplain
packagecom.iwtxokhtd.other;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
publicclassListAllProcessTest{
//列出所有的進程信息
publicstaticvoidmain(String[]args){
BufferedReaderbr=null;
try{
Processproc=Runtime.getRuntime().exec("tasklist");
br=newBufferedReader(newInputStreamReader(proc.getInputStream()));
@SuppressWarnings("unused")
Stringline=null;
System.out.println("列印所有正在運行的進程信息");
while((line=br.readLine())!=null){
System.out.println(br.readLine());
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(br!=null){
try{
br.close();
}catch(Exceptione){
e.printStackTrace();
}
}
}
}
}
(4)判斷一個具體的進程是否正在運行,如下例:
Java代碼
packagecom.iwtxokhtd.other;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
publicclassFindProcessExeTest
{
publicstaticvoidmain(String[]args){
if(findProcess("QQ.exe")){
System.out.println("------判斷指定的進程是否在運行------");
System.out.println("QQ.exe該進程正在運行!");
}else{
System.out.println("------判斷指定的進程是否在運行------");
System.out.println("QQ.exe該進程沒有在運行!");
}
}
(StringprocessName){
BufferedReaderbr=null;
try{
//下面這句是列出含有processName的進程圖像名
Processproc=Runtime.getRuntime().exec("tasklist/FI/"IMAGENAMEeq"+processName+"/"");
br=newBufferedReader(newInputStreamReader(proc.getInputStream()));
Stringline=null;
while((line=br.readLine())!=null){
//判斷指定的進程是否在運行
if(line.contains(processName)){
returntrue;
}
}
returnfalse;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}finally{
if(br!=null){
try{
br.close();
}catch(Exceptionex){
}
}
}
}
}
[java]viewplain
packagecom.iwtxokhtd.other;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
publicclassFindProcessExeTest
{
publicstaticvoidmain(String[]args){
if(findProcess("QQ.exe")){
System.out.println("------判斷指定的進程是否在運行------");
System.out.println("QQ.exe該進程正在運行!");
}else{
System.out.println("------判斷指定的進程是否在運行------");
System.out.println("QQ.exe該進程沒有在運行!");
}
}
(StringprocessName){
BufferedReaderbr=null;
try{
//下面這句是列出含有processName的進程圖像名
Processproc=Runtime.getRuntime().exec("tasklist/FI/"IMAGENAMEeq"+processName+"/"");
br=newBufferedReader(newInputStreamReader(proc.getInputStream()));
Stringline=null;
while((line=br.readLine())!=null){
//判斷指定的進程是否在運行
if(line.contains(processName)){
returntrue;
}
}
returnfalse;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}finally{
if(br!=null){
try{
br.close();
}catch(Exceptionex){
}
}
}
}
}
其它的用法可以參考JDK文檔,這里就不一一舉例,畢竟它用得不多。
3. 在java里怎麼在一個java程序里調用運行另一個java類
先把2個文件放在同一個包下面,這樣就可以訪問另一個java程序了。
一般的方法是在A程序里實例化B類,然後通過B.方法名
去調用B類里的方法
Runtime.getRuntime().exec("外部程序");
相當於你在cmd控制台中輸入"外部程序"並回車執行
4. 如何用java運行外部程序
publicclassDemo{
publicstaticvoidmain(String[]args)throwsIOException{
Stringcmd="notepad.exe";//要打開的外部程序路徑
Runtimeruntime=Runtime.getRuntime();
Processp=runtime.exec(cmd);
}
}
以上為核心代碼,自己可以把路徑從外部傳入,再打成一個可執行文件。
5. 求教:Java程序中如何調用外部exe文件
應該把Hello.exe 改成絕對路徑例如 ("\"D:/AnyQ/Hello.exe\"");
用java調用windows系統的exe文件,比如notepad,calc之類:
public class Demo{
public static void main(String args[]){
Runtime rn=Runtime.getRuntime();
Process p=null;
try{
p=rn.exec(notepad);
}catch(Exception e){
System.out.println("Error exec notepad");
}
}
}
調用其他的可執行文件,例如:自己製作的exe,或是下載安裝的軟體
public class Demo{
public static void main(String args[]){
Runtime rn=Runtime.getRuntime();
Process p=null;
try{
p=rn.exec("\"D:/AnyQ/AnyQ.exe\"");
}catch(Exception e){
System.out.println("Error exec AnyQ");
}
}
}
:http://www.ltesting.net/ceshi/ruanjianceshikaifajishu/rjcskfyy/java/2007/0714/139153.html
6. java 中怎麼打開一個外部程序
用Runtime.getRuntime().exec()方法,方法的參數傳一個字元串,表示外部程序的exe文件的路徑。(Runtime類在java.lang包下,所以不需要另添加import語句。)例如你要運行D盤根目錄下的test.exe程序,就用下面這個語句:Runtime.getRuntime().exec("D:\\test.exe");這樣就可以打開外部程序了。