网路冷眼@BlogJava

熙熙攘攘一闲人 以冷静的眼光观察技术
posts - 88, comments - 193, trackbacks - 0, articles - 28
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

几乎所有的Java 集成开发环境都需要调用外部进程进行Java程序的构建,编译,运行和调试,Eclipse,NetBeans,JBuilder和Intellij IDLE概莫例外。在执行过程中,将提示信息以黑色全部打印在控制台里,将异常和错误以红色方式打印。以非常醒目交互体验让程序员远离枯燥和乏味。

现在让我们以Eclipse为例来看看它如何工作的,以揭开它神秘面纱,探究隐藏在后面的秘密。

上篇主要介绍了JAVA IDE Console通过采用Runtime.getRuntime.exec()执行外部程序后,将返回一个Process对象. Process对象能返回三个流:

getInputStream(),对应Process程序的标准输出流。

getErrorStream(), 对应Process程序的标准错误输出流。

getOutputStream();对应Process程序的标准输入流。

函数名之所以与Process程序的方向相反,原因是站在Java Host程序的角度讲的。

现在我们应用此原理来仿真IDE 执行外部程序的过程。

列表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

测试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();
    }

}

当ConsoleSimulator程序执行外部的run.bat时,输出如图1所示:

图1

当ConsoleSimulator程序执行外部的java test正常时,输出如图2所示:

 

图2

当ConsoleSimulator程序执行外部的java test发生异常时,输出如图3所示:

图3

综上,虽然没有在自己的GUI里将stdout和stderr进行说明,只是用ERROR>提示符和INFO>提示符进行演示,但是完全IDE Console的原理。对ConsoleSimulator稍加修改,完全放入到自己的应用程序当中去。

在我们进行Java程序开发的过程当中,可能涉及到其它的应用程序,借助这种技术,可以很好利用它们,将它们集成到自己的应用当中,将极大地缩短开发周期,何乐而不为呢!


评论

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)  回复  更多评论   

2007-05-07 08:47 by ddd
在我们进行Java程序开发的过程当中,可能涉及到其它的应用程序,借助这种技术,可以很好利用它们,将它们集成到自己的应用当中,将极大地缩短开发周期,何乐而不为呢!

根本不明白上面这些的意思。。。有现成的不用, 非要自己去写, 还改叫极大的缩短开发周期。。。

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)  回复  更多评论   

2008-03-05 18:10 by whw
怎样处理子程序的输入?

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)  回复  更多评论   

2009-05-30 09:50 by flyingpig204
如果要知道执行的程序运行的时间和占用内存该怎么做呢?

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)[未登录]  回复  更多评论   

2010-07-03 17:23 by panda
@ddd
有无数的这样的需求,只要做过项目都知道。
明明一个简单的命令行,非得集成在项目里,给一个按钮,还要显示界面,
还不做不行,这个就是TMD需求。

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)[未登录]  回复  更多评论   

2010-07-03 17:24 by panda
还有感谢LZ分享。

# re: Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)[未登录]  回复  更多评论   

2011-02-26 19:38 by 匿名
表示十分的赞同

只有注册用户登录后才能发表评论。


网站导航: