[轉載] Java中Runtime的使用

參考鏈接: Java中的JVM的關閉掛鉤

1? ? ? ? ? ? JDK中Runtime的定義??

?

?

??

?

?

?http://blog.csdn.net/lysnow_oss/archive/2007/05/12/1606349.aspx

??

?

?

?<轉載>

?

?

?那就首先說點Runtime類吧,他是一個與JVM運行時環境有關的類,這個類是Singleton的。我說幾個自己覺得重要的地方。

?

?

?1、Runtime.getRuntime()可以取得當前JVM的運行時環境,這也是在Java中唯一一個得到運行時環境的方法。

?

?

?2、Runtime上其他大部分的方法都是實例方法,也就是說每次進行運行時調用時都要用到getRuntime方法。

?

?

?3、Runtime中的exit方法是退出當前JVM的方法,估計也是唯一的一個吧,因為我看到System類中的exit實際上也是通過調用 Runtime.exit()來退出JVM的,這里說明一下Java對Runtime返回值的一般規則(后邊也提到了),0代表正常退出,非0代表異常中 止,這只是Java的規則,在各個操作系統中總會發生一些小的混淆。

?

?

??

?

?

?4、Runtime.addShutdownHook()方法可以注冊一個hook在JVM執行shutdown的過程中,方法的參數只要是一個初始化過但是沒有執行的Thread實例就可以。(注意,Java中的Thread都是執行過了就不值錢的哦)

?

?

?5、說到addShutdownHook這個方法就要說一下JVM運行環境是在什么情況下shutdown或者abort的。文檔上是這樣寫 的,當最后一個非精靈進程退出或者收到了一個用戶中斷信號、用戶登出、系統shutdown、Runtime的exit方法被調用時JVM會啟動 shutdown的過程,在這個過程開始后,他會并行啟動所有登記的shutdown hook(注意是并行啟動,這就需要線程安全和防止死鎖)。當shutdown過程啟動后,只有通過調用halt方法才能中止shutdown的過程并退 出JVM。

?

?

?那什么時候JVM會abort退出那?首先說明一下,abort退出時JVM就是停止運行但并不一定進行shutdown。這只有JVM在遇到 SIGKILL信號或者windows中止進程的信號、本地方法發生類似于訪問非法地址一類的內部錯誤時會出現。這種情況下并不能保證shutdown hook是否被執行。

?

?

??

?

?

?首先講的是?

?Runtime.exec()?

?方法的所有重載。這里要注意的有一點,就是?

?public Process exec(String [] cmdArray, String [] envp);?

?這個方法中?

?cmdArray?

?是一個執行的命令和參數的字符串數組,數組的第一個元素是要執行的命令往后依次都是命令的參數,?

?envp?

?我個人感覺應該和?

?C?

?中的?

?execve?

?中的環境變量是一樣的,?

?envp?

?中使用的是?

?name=value?

?的方式。?

?

?

??

?

?

?2? ? ? ? ? ? Runtime的構造函數和方法??

?

?

??

?

?

?Runtime是個單例類

?

?

??

?

?

? ??

? ? ?方法摘要

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?addShutdownHook 注冊新的虛擬機來關閉掛鉤。 (

? ? ?Thread? ?hook)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? int

? ? ??

? ??

? ? ?availableProcessors 向 Java 虛擬機返回可用處理器的數目。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在單獨的進程中執行指定的字符串命令。 (

? ? ?String? ?command)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在單獨的進程中執行指定命令和變量。 (

? ? ?String? [] cmdarray)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在指定環境的獨立進程中執行指定命令和變量。 (

? ? ?String? [] cmdarray,?

? ? ?String? [] envp)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在指定環境和工作目錄的獨立進程中執行指定的命令和變量。 (

? ? ?String? [] cmdarray,?

? ? ?String? [] envp,?

? ? ?File? ?dir)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在指定環境的單獨進程中執行指定的字符串命令。 (

? ? ?String? ?command,?

? ? ?String? [] envp)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?Process??

? ? ??

? ??

? ? ?exec 在有指定環境和工作目錄的獨立進程中執行指定的字符串命令。 (

? ? ?String? ?command,?

? ? ?String? [] envp,?

? ? ?File? ?dir)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?exit 通過啟動虛擬機的關閉序列,終止當前正在運行的 Java 虛擬機。 (int status)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? long

? ? ??

? ??

? ? ?freeMemory 返回 Java 虛擬機中的空閑內存量。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?gc 運行垃圾回收器。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?InputStream??

? ? ??

? ??

? ? ?getLocalizedInputStream 已過時。 從 JDK 1.1 開始,將本地編碼字節流轉換為 Unicode 字符流的首選方法是使用 InputStreamReader 和 BufferedReader 類。 (

? ? ?InputStream? ?in)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ??

? ? ?OutputStream??

? ? ??

? ??

? ? ?getLocalizedOutputStream 已過時。 從 JDK 1.1 開始,將 Unicode 字符流轉換為本地編碼字節流的首選方法是使用 OutputStreamWriter、BufferedWriter 和 PrintWriter 類。 (

? ? ?OutputStream? ?out)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ?static?

? ? ?Runtime??

? ? ??

? ??

? ? ?getRuntime 返回與當前 Java 應用程序相關的運行時對象。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?halt 強行終止目前正在運行的 Java 虛擬機。 (int status)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?load 加載作為動態庫的指定文件名。 (

? ? ?String? ?filename)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?loadLibrary 加載具有指定庫名的動態庫。 (

? ? ?String? ?libname)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? long

? ? ??

? ??

? ? ?maxMemory 返回 Java 虛擬機試圖使用的最大內存量。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? boolean

? ? ??

? ??

? ? ?removeShutdownHook 取消注冊某個先前已注冊的虛擬機關閉掛鉤。 (

? ? ?Thread? ?hook)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?runFinalization 運行掛起 finalization 的所有對象的終止方法。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ?static void

? ? ??

? ??

? ? ?runFinalizersOnExit 已過時。 此方法本身具有不安全性。它可能對正在使用的對象調用終結方法,而其他線程正在操作這些對象,從而導致不正確的行為或死鎖。 (boolean value)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? long

? ? ??

? ??

? ? ?totalMemory 返回 Java 虛擬機中的內存總量。 ()?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?traceInstructions 啟用/禁用指令跟蹤。 (boolean on)?

? ? ? ? ? ? ? ??

? ? ??

? ??

? ? ? void

? ? ??

? ??

? ? ?traceMethodCalls 啟用/禁用方法調用跟蹤。 (boolean on)?

? ? ? ? ? ? ? ??

? ? ??

?

??

?

?

?3? ? ? ? ? ? Runtime的使用??

?

?

?這個程序用exec調用了一個外部命令之后馬上使用exitValue就對其返回值進行檢查,讓我們看看會出現什么問題。

?

?

??

?

?

?import java.util.*;

? import java.io.*;

?

?

?public class BadExecJavac

? {

? public static void main(String args[])

? {

? try

? {?

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("javac");

? int exitVal = proc.exitValue();

? System.out.println("Process exitValue: " + exitVal);

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

??

?

?

?A run of BadExecJavac produces:?

?

?

? E:classescomjavaworldjpitfallsarticle2>java BadExecJavac

? java.lang.IllegalThreadStateException: process has not exited

? at java.lang.Win32Process.exitValue(Native Method)

? at BadExecJavac.main(BadExecJavac.java:13)

?

?

??

?

?

?這里看原文就可以了解,這里主要的問題就是錯誤的調用了exitValue來取得外部命令的返回值(呵呵,這個錯誤我也曾經犯過),因為 exitValue這個方法是不阻塞的,程序在調用這個方法時外部命令并沒有返回所以造成了異常的出現,這里是由另外的方法來等待外部命令執行完畢的,就 是waitFor方法,這個方法會一直阻塞直到外部命令執行結束,然后返回外部命令執行的結果,作者在這里一頓批評設計者的思路有問題,呵呵,反正我是無 所謂阿,能用就可以拉。但是作者在這里有一個說明,就是exitValue也是有好多用途的。因為當你在一個Process上調用waitFor方法時, 當前線程是阻塞的,如果外部命令無法執行結束,那么你的線程就會一直阻塞下去,這種意外會影響我們程序的執行。所以在我們不能判斷外部命令什么時候執行完 畢而我們的程序還需要繼續執行的情況下,我們就應該循環的使用exitValue來取得外部命令的返回狀態,并在外部命令返回時作出相應的處理。

?

?

??

?

?

?2、對exitValue處改進了的程序

?

?

?import java.util.*;

? import java.io.*;

?

?

?public class BadExecJavac2

? {

? public static void main(String args[])

? {

? try

? {?

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("javac");

? int exitVal = proc.waitFor();

? System.out.println("Process exitValue: " + exitVal);

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?不幸的是,這個程序也無法執行完成,它沒有輸出但卻一直懸在那里,這是為什么那?

?

?

? JDK文檔中對此有如此的解釋:因為本地的系統對標準輸入和輸出所提供的緩沖池有效,所以錯誤的對標準輸出快速的寫入和從標準輸入快速的讀入都有可能造成子進程的鎖,甚至死鎖。

?

?

? 文檔引述完了,作者又開始批評了,他說JDK僅僅說明為什么問題會發生,卻并沒有說明這個問題怎么解決,這的確是個問題哈。緊接著作者 說出自己的做法,就是在執行完外部命令后我們要控制好Process的所有輸入和輸出(視情況而定),在這個例子里邊因為調用的是Javac,而他在沒有 參數的情況下會將提示信息輸出到標準出錯,所以在下面的程序中我們要對此進行處理。

?

?

? import java.util.*;

? import java.io.*;

?

?

?public class MediocreExecJavac

? {

? public static void main(String args[])

? {

? try

? {?

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("javac");

? InputStream stderr = proc.getErrorStream();

? InputStreamReader isr = new InputStreamReader(stderr);

? BufferedReader br = new BufferedReader(isr);

? String line = null;

? System.out.println("");

? while ( (line = br.readLine()) != null)

? System.out.println(line);

? System.out.println("");

? int exitVal = proc.waitFor();

? System.out.println("Process exitValue: " + exitVal);

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

? 程序的運行結果為

?

?

?E:classescomjavaworldjpitfallsarticle2>java MediocreExecJavac

??

? Usage: javac?

?

?

?where includes:

? -g Generate all debugging info

? -g:none Generate no debugging info

? -g:{lines,vars,source} Generate only some debugging info

? -O Optimize; may hinder debugging or enlarge class files

? -nowarn Generate no warnings

? -verbose Output messages about what the compiler is doing

? -deprecation Output source locations where deprecated APIs are used

? -classpath Specify where to find user class files

? -sourcepath Specify where to find input source files

? -bootclasspath Override location of bootstrap class files

? -extdirs Override location of installed extensions

? -d Specify where to place generated class files

? -encoding Specify character encoding used by source files

? -target Generate class files for specific VM version

??

? Process exitValue: 2

?

?

? 哎,不管怎么說還是出來了結果,作者作了一下總結,就是說,為了處理好外部命令大量輸出的情況,你要確保你的程序處理好外部命令所需要的輸入或者輸出。

?

?

? 下一個題目,當我們調用一個我們認為是可執行程序的時候容易發生的錯誤(今天晚上我剛剛犯這個錯誤,沒事做這個練習時候發生的)

?

?

?import java.util.*;

? import java.io.*;

?

?

?public class BadExecWinDir

? {

? public static void main(String args[])

? {

? try

? {?

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("dir");

? InputStream stdin = proc.getInputStream();

? InputStreamReader isr = new InputStreamReader(stdin);

? BufferedReader br = new BufferedReader(isr);

? String line = null;

? System.out.println("");

? while ( (line = br.readLine()) != null)

? System.out.println(line);

? System.out.println("");

? int exitVal = proc.waitFor();?

? System.out.println("Process exitValue: " + exitVal);

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?A run of BadExecWinDir produces:?

?

?

? E:classescomjavaworldjpitfallsarticle2>java BadExecWinDir

? java.io.IOException: CreateProcess: dir error=2

? at java.lang.Win32Process.create(Native Method)

? at java.lang.Win32Process.(Unknown Source)

? at java.lang.Runtime.execInternal(Native Method)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at BadExecWinDir.main(BadExecWinDir.java:12)

?

?

? 說實在的,這個錯誤還真是讓我摸不著頭腦,我覺得在windows中返回2應該是沒有找到這個文件的緣故,可能windows 2000中只有cmd命令,dir命令不是當前環境變量能夠解釋的吧。我也不知道了,慢慢往下看吧。

?

?

?嘿,果然和作者想的一樣,就是因為dir命令是由windows中的解釋器解釋的,直接執行dir時無法找到dir.exe這個命令,所以會出 現文件未找到這個2的錯誤。如果我們要執行這樣的命令,就要先根據操作系統的不同執行不同的解釋程序command.com 或者cmd.exe。

?

?

?作者對上邊的程序進行了修改

?

?

?import java.util.*;

? import java.io.*;

?

?

?class StreamGobbler extends Thread

? {

? InputStream is;

? String type;

?

?

?StreamGobbler(InputStream is, String type)

? {

? this.is = is;

? this.type = type;

? }

?

?

?public void run()

? {

? try

? {

? InputStreamReader isr = new InputStreamReader(is);

? BufferedReader br = new BufferedReader(isr);

? String line=null;

? while ( (line = br.readLine()) != null)

? System.out.println(type + ">" + line);?

? } catch (IOException ioe)

? {

? ioe.printStackTrace();?

? }

? }

? }

?

?

?public class GoodWindowsExec

? {

? public static void main(String args[])

? {

? if (args.length < 1)

? {

? System.out.println("USAGE: java GoodWindowsExec ");

? System.exit(1);

? }

?

?

?try

? {?

? String osName = System.getProperty("os.name" );

? String[] cmd = new String[3];

?

?

?if( osName.equals( "Windows NT" ) )

? {

? cmd[0] = "cmd.exe" ;

? cmd[1] = "/C" ;

? cmd[2] = args[0];

? }

? else if( osName.equals( "Windows 95" ) )

? {

? cmd[0] = "command.com" ;

? cmd[1] = "/C" ;

? cmd[2] = args[0];

? }

?

?

?Runtime rt = Runtime.getRuntime();

? System.out.println("Execing " + cmd[0] + " " + cmd[1]?

? + " " + cmd[2]);

? Process proc = rt.exec(cmd);

? // any error message?

? StreamGobbler errorGobbler = new?

? StreamGobbler(proc.getErrorStream(), "ERROR");?

?

?

?// any output?

? StreamGobbler outputGobbler = new?

? StreamGobbler(proc.getInputStream(), "OUTPUT");

?

?

?// kick them off

? errorGobbler.start();

? outputGobbler.start();

?

?

?// any error???

? int exitVal = proc.waitFor();

? System.out.println("ExitValue: " + exitVal);?

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?Running GoodWindowsExec with the dir command generates:?

?

?

? E:classescomjavaworldjpitfallsarticle2>java GoodWindowsExec "dir *.java"

? Execing cmd.exe /C dir *.java

? OUTPUT> Volume in drive E has no label.

? OUTPUT> Volume Serial Number is 5C5F-0CC9

? OUTPUT>

? OUTPUT> Directory of E:classescomjavaworldjpitfallsarticle2

? OUTPUT>

? OUTPUT>10/23/00 09:01p 805 BadExecBrowser.java

? OUTPUT>10/22/00 09:35a 770 BadExecBrowser1.java

? OUTPUT>10/24/00 08:45p 488 BadExecJavac.java

? OUTPUT>10/24/00 08:46p 519 BadExecJavac2.java

? OUTPUT>10/24/00 09:13p 930 BadExecWinDir.java

? OUTPUT>10/22/00 09:21a 2,282 BadURLPost.java

? OUTPUT>10/22/00 09:20a 2,273 BadURLPost1.java

? ... (some output omitted for brevity)

? OUTPUT>10/12/00 09:29p 151 SuperFrame.java

? OUTPUT>10/24/00 09:23p 1,814 TestExec.java

? OUTPUT>10/09/00 05:47p 23,543 TestStringReplace.java

? OUTPUT>10/12/00 08:55p 228 TopLevel.java

? OUTPUT> 22 File(s) 46,661 bytes

? OUTPUT> 19,678,420,992 bytes free

? ExitValue: 0

?

?

?這里作者教了一個windows中很有用的方法,呵呵,至少我是不知道的,就是cmd.exe /C +一個windows中注冊了后綴的文檔名,windows會自動地調用相關的程序來打開這個文檔,我試了一下,的確很好用,但是好像文件路徑中有空格的 話就有點問題,我加上引號也無法解決。

?

?

?這里作者強調了一下,不要假設你執行的程序是可執行的程序,要清楚自己的程序是單獨可執行的還是被解釋的,本章的結束作者會介紹一個命令行工具來幫助我們分析。

?

?

?這里還有一點,就是得到process的輸出的方式是getInputStream,這是因為我們要從Java 程序的角度來看,外部程序的輸出對于Java來說就是輸入,反之亦然。

?

?

? 最后的一個漏洞的地方就是錯誤的認為exec方法會接受所有你在命令行或者Shell中輸入并接受的字符串。這些錯誤主要出現在命令作 為參數的情況下,程序員錯誤的將所有命令行中可以輸入的參數命令加入到exec中(這段翻譯的不好,湊合看吧)。下面的例子中就是一個程序員想重定向一個 命令的輸出。

?

?

? import java.util.*;

? import java.io.*;

?

?

?// StreamGobbler omitted for brevity

?

?

?public class BadWinRedirect

? {

? public static void main(String args[])

? {

? try

? {?

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("java jecho 'Hello World' > test.txt");

? // any error message?

? StreamGobbler errorGobbler = new?

? StreamGobbler(proc.getErrorStream(), "ERROR");?

?

?

?// any output?

? StreamGobbler outputGobbler = new?

? StreamGobbler(proc.getInputStream(), "OUTPUT");

?

?

?// kick them off

? errorGobbler.start();

? outputGobbler.start();

?

?

?// any error???

? int exitVal = proc.waitFor();

? System.out.println("ExitValue: " + exitVal);?

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?Running BadWinRedirect produces:?

?

?

? E:classescomjavaworldjpitfallsarticle2>java BadWinRedirect

? OUTPUT>'Hello World' > test.txt

? ExitValue: 0

?

?

?程序員的本意是將Hello World這個輸入重訂向到一個文本文件中,但是這個文件并沒有生成,jecho僅僅是將命令行中的參數輸出到標準輸出中,用戶覺得可以像dos中重定向 一樣將輸出重定向到一個文件中,但這并不能實現,用戶錯誤的將exec認為是一個shell解釋器,但它并不是,如果你想將一個程序的輸出重定向到其他的 程序中,你必須用程序來實現他。可用java.io中的包。

?

?

? import java.util.*;

? import java.io.*;

?

?

?class StreamGobbler extends Thread

? {

? InputStream is;

? String type;

? OutputStream os;

?

?

?StreamGobbler(InputStream is, String type)

? {

? this(is, type, null);

? }

?

?

?StreamGobbler(InputStream is, String type, OutputStream redirect)

? {

? this.is = is;

? this.type = type;

? this.os = redirect;

? }

?

?

?public void run()

? {

? try

? {

? PrintWriter pw = null;

? if (os != null)

? pw = new PrintWriter(os);

?

?

?InputStreamReader isr = new InputStreamReader(is);

? BufferedReader br = new BufferedReader(isr);

? String line=null;

? while ( (line = br.readLine()) != null)

? {

? if (pw != null)

? pw.println(line);

? System.out.println(type + ">" + line);?

? }

? if (pw != null)

? pw.flush();

? } catch (IOException ioe)

? {

? ioe.printStackTrace();?

? }

? }

? }

?

?

?public class GoodWinRedirect

? {

? public static void main(String args[])

? {

? if (args.length < 1)

? {

? System.out.println("USAGE java GoodWinRedirect ");

? System.exit(1);

? }

?

?

?try

? {?

? FileOutputStream fos = new FileOutputStream(args[0]);

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec("java jecho 'Hello World'");

? // any error message?

? StreamGobbler errorGobbler = new?

? StreamGobbler(proc.getErrorStream(), "ERROR");?

?

?

?// any output?

? StreamGobbler outputGobbler = new?

? StreamGobbler(proc.getInputStream(), "OUTPUT", fos);

?

?

?// kick them off

? errorGobbler.start();

? outputGobbler.start();

?

?

?// any error???

? int exitVal = proc.waitFor();

? System.out.println("ExitValue: " + exitVal);

? fos.flush();

? fos.close();?

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?Running GoodWinRedirect produces:?

?

?

? E:classescomjavaworldjpitfallsarticle2>java GoodWinRedirect test.txt

? OUTPUT>'Hello World'

? ExitValue: 0

?

?

?這里就不多說了,看看就明白,緊接著作者給出了一個監測命令的小程序

?

?

?import java.util.*;

? import java.io.*;

?

?

?// class StreamGobbler omitted for brevity

?

?

?public class TestExec

? {

? public static void main(String args[])

? {

? if (args.length < 1)

? {

? System.out.println("USAGE: java TestExec "cmd"");

? System.exit(1);

? }

?

?

?try

? {

? String cmd = args[0];

? Runtime rt = Runtime.getRuntime();

? Process proc = rt.exec(cmd);

?

?

?// any error message?

? StreamGobbler errorGobbler = new?

? StreamGobbler(proc.getErrorStream(), "ERR");?

?

?

?// any output?

? StreamGobbler outputGobbler = new?

? StreamGobbler(proc.getInputStream(), "OUT");

?

?

?// kick them off

? errorGobbler.start();

? outputGobbler.start();

?

?

?// any error???

? int exitVal = proc.waitFor();

? System.out.println("ExitValue: " + exitVal);

? } catch (Throwable t)

? {

? t.printStackTrace();

? }

? }

? }

?

?

?對這個程序進行運行:?

? E:classescomjavaworldjpitfallsarticle2>java TestExec "e:javadocsindex.html"

? java.io.IOException: CreateProcess: e:javadocsindex.html error=193

? at java.lang.Win32Process.create(Native Method)

? at java.lang.Win32Process.(Unknown Source)

? at java.lang.Runtime.execInternal(Native Method)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at java.lang.Runtime.exec(Unknown Source)

? at TestExec.main(TestExec.java:45)

?

?

?193在windows中是說這不是一個win32程序,這說明路徑中找不到這個網頁的關聯程序,下面作者決定用一個絕對路徑來試一下。

?

?

?E:classescomjavaworldjpitfallsarticle2>java TestExec?

? "e:program filesnetscapeprogramnetscape.exe e:javadocsindex.html"

? ExitValue: 0

?

?

? 好用了,這個我也試了一下,用的是IE。

?

?

? 最后,作者總結了幾條規則,防止我們在進行Runtime.exec()調用時出現錯誤。

?

?

??

?

?

??

?

?

?在一個外部進程執行完之前你不能得到他的退出狀態?

?

?

?在你的外部程序開始執行的時候你必須馬上控制輸入、輸出、出錯這些流。?

?

?

?你必須用?

?Runtime.exec()?

?去執行程序?

?

?

?你不能象命令行一樣使用?

?Runtime.exec()?

?。?

?

?

??

?

?

??

?

?

?在nea需要動態來添加到RNC的路由,可以利用Runtime.exec方法來實現

?

?

?具體實現如下:

?

?

?其中的ip參數到時候可以是動態獲取就可以了。

?

?

??

?

?

?String[] cmds = {"cmd.exe","/c","route add 11.11.11.11 mask 255.255.255.255 11.11.11.1 metric 30 > tree.txt"};

?

?

? ? ? ? ?try {?

?

?

? ? ? ? ? ? ?Process ps = Runtime.getRuntime().exec(cmds);?

?

?

? ? ? ? ? ? ?System.out.print(loadStream (ps.getInputStream()));?

?

?

? ? ? ? ? ? ?System.err.print(loadStream (ps.getErrorStream()));?

?

?

? ? ? ? ?} catch(IOException ioe) {?

?

?

? ? ? ? ? ? ?ioe.printStackTrace();?

?

?

? ? ? ? ? }

?

?

??

?

?

? ? ? ? ?// read an input-stream into a String

?

?

? ? ?static String loadStream(InputStream in) throws IOException {?

?

?

? ? ? ? ?int ptr = 0;?

?

?

? ? ? ? ?in = new BufferedInputStream(in);?

?

?

? ? ? ? ?StringBuffer buffer = new StringBuffer();?

?

?

? ? ? ? ?while( (ptr = in.read()) != -1 ) {?

?

?

? ? ? ? ? ? ?buffer.append((char)ptr);?

?

?

? ? ? ? ?}?

?

?

? ? ? ? ?return buffer.toString();?

?

?

? ? ? }

?

?

??

?

?

?其中的 > tree.txt可以把執行這個指令的結果重新定向到一個文件里面,比如執行dir,tree等指令的時候。

?

?

??

?

?

??

?

?

?如果要執行dos以外的指令,需要指定執行工作目錄,

?

?

??

?

?

?比如執行某個exe程序的話,利用了Runtime的

?exec (?

?String [] cmdarray,??

?String [] envp,??

?File? dir)方法來實現。File是這個exe程序的目錄。?

?

?

??

?

?

?String[] cmds = {"cmd.exe","/c","radmin.exe"};

?

?

? ? ? ? ? try {

?

?

? ? ? ? ? ? ?Process ps = Runtime.getRuntime().exec(cmds,null,new File("C://Program Files//Radmin"));?

?

?

? ? ? ? ? ? ?System.out.print(loadStream(ps.getInputStream()));?

?

?

? ? ? ? ? ? ?System.err.print(loadStream(ps.getErrorStream()));?

?

?

? ? ? ? ?} catch(IOException ioe) {?

?

?

? ? ? ? ? ? ?ioe.printStackTrace();?

?

?

? ? ? ? ? }

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540433.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540433.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540433.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

窄帶物聯網(NB-IoT)初步了解

哪有什么天生如此&#xff0c;只是我們天天堅持。既然總有人要贏的話&#xff0c;為什么不能是我呢&#xff1f;[TOC] 什么是NB-Iot? 基于蜂窩的窄帶物聯網&#xff08;Narrow Band Internet of Things, NB-IoT&#xff09;成為萬物互聯網絡的一個重要分支。NB-IoT構建于蜂窩網…

ai人工智能_人工智能能力問答中的人工智能不確定性

ai人工智能1) Which of the following is true with respect to uncertainty in AI systems? Uncertainty arises when we are not 100 percent confident in our decisionsWhenever uncertainty arises, there is needs to be an estimation taken for getting to any conclu…

[轉載] 弄懂JDK、JRE和JVM到底是什么

參考鏈接&#xff1a; JDK JRE和JVM之間的區別 首先是JDK JDK(Java Development Kit) 是 Java 語言的軟件開發工具包(SDK)。 在JDK的安裝目錄下有一個jre目錄&#xff0c;里面有兩個文件夾bin和lib&#xff0c;在這里可以認為bin里的就是jvm&#xff0c;lib中則是jvm工作所需要…

mcq 隊列_人工智能搜索問題能力問題解答(MCQ)

mcq 隊列1) The main Aim of the AI system is to provide a solution for real-life problems by acting and thinking humanly. Whenever an agent is confronted by a problem, what is the first step that it follows towards searching a solution to the problem? Sear…

JavaOne大事紀:IBM談OpenJ9和Open Liberty

JavaOne大會以IBM陳述其最近對開源社區的貢獻作為開場&#xff1a;OpenJ9、Open Liberty和MicroProfile。IBM杰出工程師John Duimovich做了“IBM和Java&#xff1a;助力下一代創新”的開場演講。\\讀者可以回看演講視頻。\\Duimovich說IBM之所以致力于推動Java生態系統的創新&a…

[轉載] JVM中對象的回收過程

參考鏈接&#xff1a; JVM是否創建Main類(具有main()的類)的對象 當我們的程序開啟運行之后就&#xff0c;就會在我們的java堆中不斷的產生新的對象&#xff0c;而這是需要占用我們的存儲空間的&#xff0c;因為創建一個新的對象需要分配對應的內存空間&#xff0c;顯然我的內…

c語言格式對齊填充_C ++中類的大小 課堂上的填充和對齊| 派生類的大小

c語言格式對齊填充Prerequisite: 先決條件&#xff1a; sizeof() operator in C/C C / C 中的sizeof()運算符 Size of struct in C C中的struct大小 We know that a struct size is not only the summation of all the data members, rather its the minimum sum guaranteed. …

ELK系列~對fluentd參數的理解

這段時候一直在研究ELK框架&#xff0c;主要集成在對fluentd和nxlog的研究上&#xff0c;國內文章不多&#xff0c;主要看了一下官方的API&#xff0c;配合自己的理解&#xff0c;總結了一下&#xff0c;希望可以幫到剛入行的朋友們&#xff01; Fluentd&#xff08;日志收集與…

[轉載] Java中的50個關鍵字

參考鏈接&#xff1a; Java平臺如何獨立 Java中的50個關鍵字 關鍵字也稱為保留字&#xff0c;是指java語言中規定了特定含義的標示符。對于保留字&#xff0c;用戶只能按照系統規定的方式使用&#xff0c;不能自行定義。Java中有50個常用關鍵字&#xff1a; 與數據類型相關…

MySQL 直接存儲圖片并在 html 頁面中展示,點擊下載

數據庫實體類&#xff1a; package com.easy.kotlin.picturecrawler.entityimport java.util.* import javax.persistence.*Entity Table(indexes arrayOf(Index(name "idx_url", unique true, columnList "url"),Index(name "idx_category"…

css 文本背景色透明_如何使用CSS將文本或圖像的背景設置為透明?

css 文本背景色透明Introduction: 介紹&#xff1a; In web development, there are numerous ways by which we can style our websites or web pages. You can make use of lots of properties for creating attractive and responsive websites. 在Web開發中&#xff0c;我…

[轉載] 1.1Java使用JDBC原生方式連接MySql數據庫

參考鏈接&#xff1a; Java數據庫連接JDBC驅動程序 前言&#xff1a;今天有朋友問我原生的java連接數據庫&#xff0c;因為框架的使用&#xff0c;如果基礎不牢固的人&#xff0c;是很容易遺忘原生的連接方式。今天正好趁此做一下回顧&#xff1a; 這里只考慮原生方式&#x…

maven安裝及集成myeclipse

第一步&#xff1a;下載和安裝 1、官網下載Maven&#xff1a;http://maven.apache.org/download.cgi 2、解壓到一個文件夾2、設置環境變量&#xff1a;如&#xff1a;M2_HOME&#xff1a;D:\JAVA\apache-maven-3.0.5在path中添加;%M2_HOME%\bin;第二步&#xff1a;和MyEclipse集…

[轉載] Java泛型詳解:<T>和Class<T>的使用。泛型類,泛型方法的詳細使用實例

參考鏈接&#xff1a; Java中的main()函數是強制性的嗎 一、引入 1、泛型是什么 首先告訴大家ArrayList就是泛型。那ArrayList能完成哪些想不到的功能呢&#xff1f;先看看下面這段代碼&#xff1a; [java] view plain copy ArrayList<String> strList new ArrayL…

數字和數字根的總和_使用8086微處理器查找8位數字的數字總和

數字和數字根的總和Problem statement: 問題陳述&#xff1a; Write an assembly language program in 8086 microprocessor to find sum of digit of an 8 bits number using 8 bits operation. 在8086微處理器中編寫匯編語言程序&#xff0c;以使用8位運算找到8位數字的位數…

[轉載] Java筆試題集錦

參考鏈接&#xff1a; 關于Java中文件名和類名的誤解 Java筆試題集錦 1.MVC的各個部分都有那些技術來實現?如何實現? 答&#xff1a;MVC是Model&#xff0d;View&#xff0d;Controller的簡寫。"Model" 代表的是應用的業務邏輯&#xff08;通過JavaBean&#xff…

gcc -pthread_錯誤-在GCC Linux中使用C程序未定義對'pthread_create'的引用

gcc -pthread在Linux中修復對pthread_create的未定義引用 (Fixing undefined reference to pthread_create in Linux) This is a common error while compiling C program in GCC/G Linux. This error occurs when you are using pthread_create function to create threads in…

[轉載] Java面試題全集(上)

參考鏈接&#xff1a; 如何運行不同目錄中的Java類文件 2013年年底的時候&#xff0c;我看到了網上流傳的一個叫做《Java面試題大全》的東西&#xff0c;認真的閱讀了以后發現里面的很多題目是重復且沒有價值的題目&#xff0c;還有不少的參考答案也是錯誤的&#xff0c;于是我…

python重載運算符乘法_Python | 使用乘法運算符創建一個字符串的多個副本

python重載運算符乘法Given a string and we have to create its multiple copies by using multiplication operator in Python? 給定一個字符串&#xff0c;我們必須通過在Python中使用乘法運算符來創建其多個副本&#xff1f; If you want to create multiple copies of …

一次前端筆試總結

1.有一個長度未知的數組a&#xff0c;如果它的長度為0就把數字1添加到數組里面&#xff0c;否則按照先進先出的隊列規則讓第一個元素出隊。 分析&#xff1a;這道題主要是考核了數組的隊列方法和棧方法。另外&#xff0c;原題還有字數限制的&#xff0c;只有在字數小于30并且結…