日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java調(diào)用系統(tǒng)命令學(xué)習(xí)

 dddTTLee 2011-05-08

呵呵。。

view plaincopy to clipboardprint?
import java.io.*;  
class Exec{  
        public static void main(String []args)throws IOException{  
                //Linux系統(tǒng)命令:ls -l  
                String command = "ls -l";  
                //獲取當(dāng)前系統(tǒng)的環(huán)境。  
                Runtime rt = Runtime.getRuntime();  
                //執(zhí)行  
                Process p = null;  
                p = rt.exec(command);  
                //獲取執(zhí)行后的數(shù)據(jù)  
                BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
                String msg = null;  
                //輸出。  
                while((msg = br.readLine())!=null){  
                        System.out.println(msg);  
                }  
                br.close();  
        }  
}  
import java.io.*;
class Exec{
        public static void main(String []args)throws IOException{
                //Linux系統(tǒng)命令:ls -l
                String command = "ls -l";
                //獲取當(dāng)前系統(tǒng)的環(huán)境。
                Runtime rt = Runtime.getRuntime();
                //執(zhí)行
                Process p = null;
                p = rt.exec(command);
                //獲取執(zhí)行后的數(shù)據(jù)
                BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String msg = null;
                //輸出。
                while((msg = br.readLine())!=null){
                        System.out.println(msg);
                }
                br.close();
        }

上面的代碼比較簡單:

其中分為幾個步驟:

1.獲取當(dāng)前系統(tǒng)的運(yùn)行環(huán)境。

2.在當(dāng)前系統(tǒng)執(zhí)行系統(tǒng)命令。

3.執(zhí)行后,獲取其執(zhí)行后的數(shù)據(jù)。

4.輸出數(shù)據(jù)。

5.結(jié)束。

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

首先學(xué)習(xí)下:Process類。

簡單地測試一下:

調(diào)用Javac命令,并查看執(zhí)行命令的返回值,并輸出到控制臺上去。

  1. import java.io.IOException;   
  2. class Exec_Javac{   
  3.         public static void main(String []args)throws IOException{   
  4.                 Runtime rt = Runtime.getRuntime();   
  5.                 Process p = rt.exec("javac");   
  6.                 int exitValue = p.exitValue();   
  7.                 System.out.println("Process exitValue="+exitValue);   
  8.         }   
  9. }   
  10. //執(zhí)行結(jié)果:   
  11. Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited   
  12.     at java.lang.UNIXProcess.exitValue(UNIXProcess.java:172)   
  13.     at Exec_Javac.main(Exec_Javac.java:6)  

 

呵呵,從上面,我們可以知道,并不能得到我們想要的結(jié)果。至于什么原因呢。

下面一段話直接引用別人的:(它比較詳細(xì)地講述了出錯的原因)

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

那么好,既然出錯了,當(dāng)然要修改啦:

改為如下:

  1. import java.io.IOException;   
  2. class Exec_Javac{   
  3.         public static void main(String []args)throws IOException,InterruptedException{   
  4.                 Runtime rt = Runtime.getRuntime();   
  5.                 Process p = rt.exec("javac");   
  6.                 //int exitValue = p.exitValue();   
  7.                 int exitValue = p.waitFor();   
  8.                 System.out.println("Process exitValue="+exitValue);   
  9.         }   
  10. }   
  11. //執(zhí)行結(jié)果為   
  12. Process exitValue=2   

 

得到上面這個結(jié)果是我意想不到的。因?yàn)樵赪indows下執(zhí)行,會一直阻塞在那里。

卻我在Ubuntu里面執(zhí)行時,卻在編譯時卻卻不過,

拋出了這樣的異常:

Exec_Javac.java:7: unreported exception java.lang.InterruptedException; must be caught or declared to be thrown
        int exitValue = p.waitFor();
                                 ^
1 error

后來加上InterrupedException才可以執(zhí)行??梢允黔h(huán)境上的不同。雖然是輸出了結(jié)果,但是因?yàn)楫惓V袛嗖泡敵龅慕Y(jié)果。也不是我想要的結(jié)果。這個又是為什么呢?

以下又是引用別人的話:

JDK文檔中對此有如此的解釋:因?yàn)楸镜氐南到y(tǒng)對標(biāo)準(zhǔn)輸入和輸出所提供的緩沖池有效,所以錯誤的對標(biāo)準(zhǔn)輸出快速的寫入和從標(biāo)準(zhǔn)輸入快速的讀入都有可能造成子進(jìn)程的鎖,甚至死鎖。


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

呵呵。。不是想要的結(jié)果。當(dāng)然還是得改進(jìn)啦。

代碼如下:

  1. import java.io.IOException;   
  2. import java.io.InputStream;   
  3. import java.io.InputStreamReader ;   
  4. import java.io.BufferedReader;   
  5. class Exec_Javac{   
  6.         public static void main(String []args)throws IOException,InterruptedException{   
  7.                 Runtime rt = Runtime.getRuntime();   
  8.                 Process p = rt.exec("javac");   
  9.                 //int exitValue = p.exitValue();   
  10.                 //int exitValue = p.waitFor();   
  11.                 InputStream is = p.getErrorStream();   
  12.                 InputStreamReader isr = new InputStreamReader(is);   
  13.                 BufferedReader br = new BufferedReader(isr);   
  14.                 String line = null;   
  15.                 System.out.println("<ERROR>");   
  16.                 while((line = br.readLine())!=null){   
  17.                         System.out.println(line);   
  18.                         System.out.println("</ERROR>");   
  19.                         int exitValue = p.waitFor();   
  20.                         System.out.println("Process exitValue="+exitValue);   
  21.                 }   
  22.         }   
  23. }   
  24. //執(zhí)行結(jié)果:   
  25. <ERROR>   
  26. Usage: javac <options> <source files>   
  27. </ERROR>   
  28. Process exitValue=2  
  29. where possible options include:   
  30. </ERROR>   
  31. Process exitValue=2  
  32.   -g                         Generate all debugging info   
  33. </ERROR>   
  34. Process exitValue=2  
  35.   -g:none                    Generate no debugging info   
  36. </ERROR>   
  37. Process exitValue=2  
  38.   -g:{lines,vars,source}     Generate only some debugging info   
  39. </ERROR>   
  40. Process exitValue=2  
  41.   -nowarn                    Generate no warnings   
  42. </ERROR>   
  43. Process exitValue=2  
  44.   -verbose                   Output messages about what the compiler is doing   
  45. </ERROR>   
  46. Process exitValue=2  
  47.   -deprecation               Output source locations where deprecated APIs are used   
  48. </ERROR>   
  49. Process exitValue=2  
  50.   -classpath <path>          Specify where to find user class files and annotation processors   
  51. </ERROR>   
  52. Process exitValue=2  
  53.   -cp <path>                 Specify where to find user class files and annotation processors   
  54. </ERROR>   
  55. Process exitValue=2  
  56.   -sourcepath <path>         Specify where to find input source files   
  57. </ERROR>   
  58. Process exitValue=2  
  59.   -bootclasspath <path>      Override location of bootstrap class files   
  60. </ERROR>   
  61. Process exitValue=2  
  62.   -extdirs <dirs>            Override location of installed extensions   
  63. </ERROR>   
  64. Process exitValue=2  
  65.   -endorseddirs <dirs>       Override location of endorsed standards path   
  66. </ERROR>   
  67. Process exitValue=2  
  68.   -proc:{none,only}          Control whether annotation processing and/or compilation is done.   
  69. </ERROR>   
  70. Process exitValue=2  
  71.   -processor <class1>[,<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process   
  72. </ERROR>   
  73. Process exitValue=2  
  74.   -processorpath <path>      Specify where to find annotation processors   
  75. </ERROR>   
  76. Process exitValue=2  
  77.   -d <directory>             Specify where to place generated class files   
  78. </ERROR>   
  79. Process exitValue=2  
  80.   -s <directory>             Specify where to place generated source files   
  81. </ERROR>   
  82. Process exitValue=2  
  83.   -implicit:{none,class}     Specify whether or not to generate class files for implicitly referenced files    
  84. </ERROR>   
  85. Process exitValue=2  
  86.   -encoding <encoding>       Specify character encoding used by source files   
  87. </ERROR>   
  88. Process exitValue=2  
  89.   -source <release>          Provide source compatibility with specified release   
  90. </ERROR>   
  91. Process exitValue=2  
  92.   -target <release>          Generate class files for specific VM version   
  93. </ERROR>   
  94. Process exitValue=2  
  95.   -version                   Version information   
  96. </ERROR>   
  97. Process exitValue=2  
  98.   -help                      Print a synopsis of standard options   
  99. </ERROR>   
  100. Process exitValue=2  
  101.   -Akey[=value]              Options to pass to annotation processors   
  102. </ERROR>   
  103. Process exitValue=2  
  104.   -X                         Print a synopsis of nonstandard options   
  105. </ERROR>   
  106. Process exitValue=2  
  107.   -J<flag>                   Pass <flag> directly to the runtime system   
  108. </ERROR>   
  109. Process exitValue=2  
  110. </ERROR>   
  111. Process exitValue=2  

 

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

其實(shí)呀。還有其他,下篇再講啦。

這會總算得到結(jié)果啦。不過在ubuntu里面跟在windows里面得到的結(jié)果有點(diǎn)不一樣。

大家注意下。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多