網(wǎng)路冷眼@BlogJava

          熙熙攘攘一閑人 以冷靜的眼光觀察技術(shù)
          posts - 88, comments - 193, trackbacks - 0, articles - 28
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          幾乎所有的Java 集成開發(fā)環(huán)境都需要調(diào)用外部進(jìn)程進(jìn)行Java程序的構(gòu)建,編譯,運(yùn)行和調(diào)試,Eclipse,NetBeans,JBuilder和Intellij IDLE概莫例外。在執(zhí)行過(guò)程中,將提示信息以黑色全部打印在控制臺(tái)里,將異常和錯(cuò)誤以紅色方式打印。以非常醒目交互體驗(yàn)讓程序員遠(yuǎn)離枯燥和乏味。

          現(xiàn)在讓我們以Eclipse為例來(lái)看看它如何工作的,以揭開它神秘面紗,探究隱藏在后面的秘密。

          上篇主要介紹了JAVA IDE Console通過(guò)采用Runtime.getRuntime.exec()執(zhí)行外部程序后,將返回一個(gè)Process對(duì)象. Process對(duì)象能返回三個(gè)流:

          getInputStream(),對(duì)應(yīng)Process程序的標(biāo)準(zhǔn)輸出流。

          getErrorStream(), 對(duì)應(yīng)Process程序的標(biāo)準(zhǔn)錯(cuò)誤輸出流。

          getOutputStream();對(duì)應(yīng)Process程序的標(biāo)準(zhǔn)輸入流。

          函數(shù)名之所以與Process程序的方向相反,原因是站在Java Host程序的角度講的。

          現(xiàn)在我們應(yīng)用此原理來(lái)仿真IDE 執(zhí)行外部程序的過(guò)程。

          列表1:ConsoleSimulator.java

          package  helloworld;

          import  java.io.BufferedReader;
          import  java.io.IOException;
          import  java.io.InputStream;
          import  java.io.InputStreamReader;
          import  java.io.OutputStream;

          /**
           * Class for console simulation
           * 
           * 
          @author  lewhwa
           
          */
          public   class  ConsoleSimulator  implements  Runnable {
              
          private   volatile   boolean  isStop  =   false ;

              
          private   static   final   int  INFO  =   0 ;

              
          private   static   final   int  ERROR  =   1 ;

              
          private  InputStream is;

              
          private   int  type;

              
          /**  Creates a new instance of StreamInterceptor  */
              
          public  ConsoleSimulator(InputStream is,  int  type) {
                  
          this .is  =  is;
                  
          this .type  =  type;
              }

              
          public   void  run() {
                  InputStreamReader isr 
          =   new  InputStreamReader(is);
                  BufferedReader reader 
          =   new  BufferedReader(isr);
                  String s;
                  
          try  {
                      
          while  (( ! isStop)  &&  (s  =  reader.readLine())  !=   null ) {
                          
          if  (s.length()  !=   0 ) {
                              
          if  (type  ==  INFO) {
                                  System.out.println(
          " INFO> "   +  s);
                              } 
          else  {
                                  System.err.println(
          " ERROR> "   +  s);
                              }
                              
          try  {
                                  Thread.sleep(
          10 );
                              } 
          catch  (InterruptedException ex) {
                                  ex.printStackTrace();
                              }
                          }
                      }
                  } 
          catch  (IOException ex) {
                      ex.printStackTrace();
                  }
              }

              
          public   void  stop() {
                  isStop 
          =   true ;
              }

              
          public   static   void  main(String[] args)  throws  IOException,
                      InterruptedException {
                  
          // Process child = Runtime.getRuntime().exec("run.bat");
                  Process child = Runtime.getRuntime().exec( " java -classpath bin helloworld.Test " );
                  OutputStream os 
          =  child.getOutputStream();
                  InputStream stdin 
          =  child.getInputStream(); //
                  InputStream stderr  =  child.getErrorStream();
                  Thread tIn 
          =   new  Thread( new  ConsoleSimulator(stdin, INFO));
                  Thread tErr 
          =   new  Thread( new  ConsoleSimulator(stderr, ERROR));
                  tIn.start();
                  tErr.start();
                  
          int  result  =  child.waitFor();
                  tIn.join();
                  tErr.join();
                  
          if  (result  ==   0 ) {
                      System.out.println(
          " SUCCESS! " );
                  } 
          else  {
                      System.out.println(
          " FAILED! " );
                  }
              }
          }

          外部Bat文件:

          列表2

          time  / t
          cmd.exe 
          / / Q copy 
          javac
          cmd.exe 
          / C tree
          rem c:\Designer_v5.
          1 .0_win32_x86.exe c:\Designer_v5. 1 .0_win32_x861.exe
          time 
          / t

          測(cè)試Java類Test.java

          列表3:

           

           

          package helloworld;

          import java.io.BufferedReader;
          import java.io.FileReader;
          import java.io.IOException;


          /**Test Class
           * 
          @author lewhwa
           * 
           
          */
          public class Test {

              
          public static void main(String[] args) throws IOException {

                  FileReader fir 
          = new FileReader("src/helloworld/Test1.java");
                  BufferedReader br 
          = new BufferedReader(fir);
                  String s;
                  
          while((s=br.readLine())!=null){
                      System.out.println(s);
                  }
                  fir.close();
              }

          }

          當(dāng)ConsoleSimulator程序執(zhí)行外部的run.bat時(shí),輸出如圖1所示:

          圖1

          當(dāng)ConsoleSimulator程序執(zhí)行外部的java test正常時(shí),輸出如圖2所示:

           

          圖2

          當(dāng)ConsoleSimulator程序執(zhí)行外部的java test發(fā)生異常時(shí),輸出如圖3所示:

          圖3

          綜上,雖然沒(méi)有在自己的GUI里將stdout和stderr進(jìn)行說(shuō)明,只是用ERROR>提示符和INFO>提示符進(jìn)行演示,但是完全I(xiàn)DE Console的原理。對(duì)ConsoleSimulator稍加修改,完全放入到自己的應(yīng)用程序當(dāng)中去。

          在我們進(jìn)行Java程序開發(fā)的過(guò)程當(dāng)中,可能涉及到其它的應(yīng)用程序,借助這種技術(shù),可以很好利用它們,將它們集成到自己的應(yīng)用當(dāng)中,將極大地縮短開發(fā)周期,何樂(lè)而不為呢!


          評(píng)論

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)  回復(fù)  更多評(píng)論   

          2007-05-07 08:47 by ddd
          在我們進(jìn)行Java程序開發(fā)的過(guò)程當(dāng)中,可能涉及到其它的應(yīng)用程序,借助這種技術(shù),可以很好利用它們,將它們集成到自己的應(yīng)用當(dāng)中,將極大地縮短開發(fā)周期,何樂(lè)而不為呢!

          根本不明白上面這些的意思。。。有現(xiàn)成的不用, 非要自己去寫, 還改叫極大的縮短開發(fā)周期。。。

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)  回復(fù)  更多評(píng)論   

          2008-03-05 18:10 by whw
          怎樣處理子程序的輸入?

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)  回復(fù)  更多評(píng)論   

          2009-05-30 09:50 by flyingpig204
          如果要知道執(zhí)行的程序運(yùn)行的時(shí)間和占用內(nèi)存該怎么做呢?

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)[未登錄](méi)  回復(fù)  更多評(píng)論   

          2010-07-03 17:23 by panda
          @ddd
          有無(wú)數(shù)的這樣的需求,只要做過(guò)項(xiàng)目都知道。
          明明一個(gè)簡(jiǎn)單的命令行,非得集成在項(xiàng)目里,給一個(gè)按鈕,還要顯示界面,
          還不做不行,這個(gè)就是TMD需求。

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)[未登錄](méi)  回復(fù)  更多評(píng)論   

          2010-07-03 17:24 by panda
          還有感謝LZ分享。

          # re: Java調(diào)用外部進(jìn)程并攔截輸入輸出流--Java IDE Console解密(下篇)[未登錄](méi)  回復(fù)  更多評(píng)論   

          2011-02-26 19:38 by 匿名
          表示十分的贊同
          主站蜘蛛池模板: 云龙县| 通道| 剑河县| 曲松县| 浦江县| 台山市| 文化| 洛宁县| 克拉玛依市| 揭东县| 蓬安县| 波密县| 大足县| 上犹县| 甘南县| 奉化市| 太谷县| 萨迦县| 齐齐哈尔市| 城市| 衡南县| 保定市| 海丰县| 固原市| 进贤县| 县级市| 石楼县| 绩溪县| 汕头市| 安多县| 新营市| 晋中市| 金溪县| 洛扎县| 宣威市| 光山县| 临沂市| 盖州市| 道真| 平顺县| 环江|