從java執行另一個應用程序,java運行另一個程序

本文目錄一覽:

如何利用當前運行的一個java程序去執行另外一個java程序

這個問題比較普遍,有多種不同的解決方法。

比較常用的,就是在B程序中添加Log文件機制,隨時記錄B程序的執行狀態,或者只記錄B程序捕捉到的異常,A程序需要查看B程序執行狀態的時候就讀取B的log文件,進行分析。

另一種方法是通過B程序的結束返回代碼來判斷B的退出原因。任何一種編程語言都提供程序返回代碼,比如java的System.exit(code)、C#的Environment.Exit(code)等等,其中的code是一個整數,表明了程序退出的時候是正常退出還是異常退出。只需要在A程序中判斷這個值就能知道B程序是因為什麼退出的。

第三種方法是通過第三方的腳本語言(比如TCL、Python)來分別執行A程序和B程序並監控兩個程序的狀態,並且可以把兩個程序做成模塊化來調用執行。這種方法最強大,也最靈活,能夠解決兩個程序運行時候的互鎖等問題,但是也最複雜。

根據你的情況,第二種方法最合適。

如何在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)ProcessBuilder

import 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();

}

}

}

java如何調用另個程序的main函數

Main方法是用static修飾的,有2種方法可以調用:

1、類名.main(參數);

2、new創建實例,實例.main(參數);

這個地方注意必須傳遞字符串數組的參數 或者 null !另外舉一個用反射機制調用Main方法的例子。

這個類是被調用的main方法類:

Java代碼:

public class Run

{

public static void main(String[] args)

{

String str=args[0]+”Hello World”;

System.out.println(str);

}

}

下面是調用main方法的類:

Java代碼:

public class JobRun

{

public static void main(String[] args)

{

String idStr = “YAya”;

try

{

Method method = Run.class.getMethod(“main”, String[].class);

method.invoke(null, (Object) new String[] { idStr });

}

catch (Exception e)

{

e.printStackTrace();

}

}

}

擴展資料:

main方法是一個特殊的方法,是程序執行的入口,一個Java程序從main方法開始執行。Java虛擬機在執行Java程序之前會事先分配一個主線程,然後在主線程裏面執行我們這個main方法。

線程就是一個程序裏面不同的執行路徑!總之,就記住,Java程序從main方法開始執行,

比如:

public static void main(String[] args) {

System.out.println(“nihao”);

}

在這裡當程序運行的時候,從main方法進來,然後做的第一件事就是System.out.println(“nihao”);

注意: main方法執行結束,程序也就執行結束了!

參考資料:百度百科-Java

百度百科-main函數

在java里怎麼在一個java程序里調用運行另一個java類?

先把2個文件放在同一個包下面,這樣就可以訪問另一個java程序了。

一般的方法是在A程序里實例化B類,然後通過B.方法名

去調用B類里的方法

Runtime.getRuntime().exec(“外部程序”);

相當於你在cmd控制台中輸入”外部程序”並回車執行

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/196141.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-03 09:53
下一篇 2024-12-03 09:53

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python應用程序的全面指南

    Python是一種功能強大而簡單易學的編程語言,適用於多種應用場景。本篇文章將從多個方面介紹Python如何應用於開發應用程序。 一、Web應用程序 目前,基於Python的Web…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Ojlat:一款快速開發Web應用程序的框架

    Ojlat是一款用於快速開發Web應用程序的框架。它的主要特點是高效、易用、可擴展且功能齊全。通過Ojlat,開發人員可以輕鬆地構建出高質量的Web應用程序。本文將從多個方面對Oj…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29

發表回復

登錄後才能評論