Ⅰ 如何在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();
}
}
}
Ⅱ 怎麼運行Java程序
輸入
D: 進入d盤,如果你的java文件在文件夾中,就cd 進入文件夾
javac xxxx.java
java xxxx;(這樣是java文件中沒有pagkage xxx);
別:不知你設置path了沒?
Ⅲ 如何在cmd下執行java程序謝謝
如圖新建一個hello.java文件,寫上你的代碼。
拓展:Java是一門面向對象編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特徵。Java語言作為靜態面向對象編程語言的代表,極好地實現了面向對象理論,允許程序員以優雅的思維方式進行復雜的編程 。
Ⅳ java是什麼何運行java程序
java它不是軟體,這里給各位初學者們詳細解釋一下。簡單來說java它是個面向網路的程序設計語言,用來讓程序員創建應用程序,這些應用程序可以通過網路下載,而且可在任何計算平台上安全地運行。如果再加上萬維網和公司內部網體系,你將會擁有一個標準的網路計算環境,Java作為一個分布式的,面向對象的程序設計語言,可以讓位於任何地方的任何計算機應用網路上的應用程序。
如果在商業角度看待Java,Java是個時髦話。同不少已經有20年歷史的其他程序設計語言相比,Java吸收了計算機科學領域的各種最新成果,另外一方面,由於Java還比較年輕,它缺少諸如VisualBasic或C++那樣的豐富的編程工具的支持。
同C++一樣,Java是個面向對象的語言,這就意味著軟體可以以部件的形式編制,為了滿足某種任務,軟部件可以互相配合。運行Java,不必非得在網路環境中進行,Java同其他傳統的諸如COBOL或Basic這樣的程序設計語言一樣,可以創建獨立運行的應用程序。只不過Java對互聯網上的應用開發更拿手。
Java適宜於互聯網的開發應用,其中一個原因是它使用了虛擬機,虛擬機是個用來解釋Java指令的軟體包,可以讓Java在任何機器上運行,比如有運行在Mac或UNIX下的虛擬機軟體包。虛擬機並不是Java語言本身,它是個為特定機器編寫的解釋器軟體。Java的虛擬機策略就相當於世界語,這是個人造的國際語言,目的是使得不同語言之間的翻譯和溝通更加容易。
要稱作一個通用的計算機語言,Java是最適合不過的,這意味著它可以在所有的計算機上運行,(盡管需要為各種機器編寫Java虛擬機軟體),可以根據需要提供軟部件,並且具有內在的安全機制。
用Java編寫的操作系統,稱為JavaOS,是個基於語言的操作系統,它看起來似乎沒有機會來占據PC市場。但是它為MicrosoftWindows和MacOS未來的發展提供了線索。它也許將來會應用到各種儀器設備中,包括電視遙控器和溫控器。
基於網路的內容供應商對Java技術很感興趣,因為它增加了交互性和動畫功能,這是吸引觀眾的關鍵因素。對於軟體商來說,Java有希望可以讓人們採用租用軟體的方式,諸如字處理器或者電子表格軟體,而無需購買軟體,這就改變了目前的商業模式。
Ⅳ 執行Java程序的命令是什麼
cmd命令進入dos界面,進入.java對應文件的文件夾,然後執行javac 文件名.java命令
Ⅵ 運行一個java程序的步驟是怎樣的請做詳細說明!
Java程序從源文件創建到程序運行要經過兩大步驟:1、源文件由編譯器編譯成位元組碼(ByteCode)
2、位元組碼由java虛擬機解釋運行。因為java程序既要編譯同時也要經過JVM的解釋運行,所以說Java被稱為半解釋語言( "semi-interpreted" language)。
下面通過以下這個java程序,來說明java程序從編譯到最後運行的整個流程。代碼如下:
//MainApp.java
public class MainApp {
public static void main(String[] args) {
Animal animal = new Animal("Puppy");
animal.printName();
}
}
//Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void printName() {
System.out.println("Animal ["+name+"]");
}
}
第一步(編譯): 創建完源文件之後,程序會先被編譯為.class文件。Java編譯一個類時,如果這個類所依賴的類還沒有被編譯,編譯器就會先編譯這個被依賴的類,然後引用,否則直接引用,這個有點象make。如果java編譯器在指定目錄下找不到該類所其依賴的類的.class文件或者.java源文件的話,編譯器話報「cant find symbol」的錯誤。
編譯後的位元組碼文件格式主要分為兩部分:常量池和方法位元組碼。常量池記錄的是代碼出現過的所有token(類名,成員變數名等等)以及符號引用(方法引用,成員變數引用等等);方法位元組碼放的是類中各個方法的位元組碼。下面是MainApp.class通過反匯編的結果,我們可以清楚看到.class文件的結構:
第二步(運行):java類運行的過程大概可分為兩個過程:1、類的載入 2、類的執行。需要說明的是:JVM主要在程序第一次主動使用類的時候,才會去載入該類。也就是說,JVM並不是在一開始就把一個程序就所有的類都載入到內存中,而是到不得不用的時候才把它載入進來,而且只載入一次。
下面是程序運行的詳細步驟:
在編譯好java程序得到MainApp.class文件後,在命令行上敲java AppMain。系統就會啟動一個jvm進程,jvm進程從classpath路徑中找到一個名為AppMain.class的二進制文件,將MainApp的類信息載入到運行時數據區的方法區內,這個過程叫做MainApp類的載入。
然後JVM找到AppMain的主函數入口,開始執行main函數。
main函數的第一條命令是Animal animal = new Animal("Puppy");就是讓JVM創建一個Animal對象,但是這時候方法區中沒有Animal類的信息,所以JVM馬上載入Animal類,把Animal類的類型信息放到方法區中。
載入完Animal類之後,Java虛擬機做的第一件事情就是在堆區中為一個新的Animal實例分配內存, 然後調用構造函數初始化Animal實例,這個Animal實例持有著指向方法區的Animal類的類型信息(其中包含有方法表,java動態綁定的底層實現)的引用。
當使用animal.printName()的時候,JVM根據animal引用找到Animal對象,然後根據Animal對象持有的引用定位到方法區中Animal類的類型信息的方法表,獲得printName()函數的位元組碼的地址。
開始運行printName()函數。
特別說明:java類中所有public和protected的實例方法都採用動態綁定機制,所有私有方法、靜態方法、構造器及初始化方法<clinit>都是採用靜態綁定機制。而使用動態綁定機制的時候會用到方法表,靜態綁定時並不會用到。
Ⅶ 怎樣用cmd命令來執行java程序
cd是cmd的命令,用於對文件夾進行操作.cd 文件夾名用於把目錄跳轉到目標文件夾.
首先用cd命令把游標指向class文件存在的目錄,然後直接java 你的文件名運行
Ⅷ 如何運行JAVA
第一步:下載並安裝JDK 6.0,安裝路勁為: C:\java\jdk1.6 .
第二步:對「我的電腦」按右鍵,選「屬性」,在「系統屬性」窗口中選「高級」標簽,再按「環境變數」按鈕,彈出一個「環境變數」的窗口,在系統變數中新建一個變數,變數名為「JAVA_HOME「,變數值為"C:\java\jdk1.6";如果存在"PATH"變數名,按編輯,在變數值最前面輸入"C:\java\jdk1.6\bin;".(注意以分號結尾,沒有引號.如果沒有"PATH",點擊新建一個"PATH"變數名,變數值一樣).
第三步:單擊Windows xp的「開始」->「運行」,在彈出的運行窗口中輸入cmd,按回車,打開一個命令行窗口,輸入javac,將會看見一系列javac常用參數選項. 恭喜你java環境安裝成功了.
第四步:開始編程(注意先雙擊打開"我的電腦",在"工具" ->"文件夾選項" -> 點擊"查看"選項 ->在"高級設置"中找到"隱藏已知文件類型的擴展名"前面的小勾去掉)。在C盤的根目錄中新建一個子目錄,名為"JavaTest」,以作為存放 Java源代碼的地方。在JavaTest文件夾中,新建文本文檔, 把「新建 文本文檔.txt」改為"HelloWorld.java"。用記事本打開"HelloWorld.java", 輸入:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world!");
System.out.println("恭喜你成功運行了第一個java應用程序!");
}
}
注意源文件名必須與類名相同,且類修飾符為public,文件名後綴為".java".保存文件.
第五步:在命令行窗口中輸入 cd C:\JavaTest,將當前路徑轉入JavaTest目錄中。然後,輸入 javac HelloWorld.java,JDK就在JavaTest文件夾中編譯生成一個HelloWorld.class的類文件。
第六步:在命令行窗口中輸入 java HelloWorld,(注意沒有.class後綴)屏幕出現了
Hello world!
恭喜你成功運行了第一個java應用程序!
表示成功了,也就順利地編譯及運行了第一個Java應用程序。
Ⅸ 如何用命令方式運行java程序
寫好你的java文件,打開你的命令提示符,切換到你文件的目錄,【javac+XXXX.java】先編譯你的Java文件,帶後綴名java,再執行 【java +「文件名」】命令