`

Java调用外部进程并拦截输出流--Java IDE Console解密(下篇)

    博客分类:
  • Java
阅读更多

几乎所有的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程序开发的过程当中,可能涉及到其它的应用程序,借助这种技术,可以很好利用它们,将它们集成到自己的应用当中,将极大地缩短开发周期,何乐而不为呢!

分享到:
评论
3 楼 javatar 2007-01-17  
Stream重定向的基本知识,注意RuntimePermission的控制。
2 楼 yongweiking 2007-01-17  
太强了,顶一个!
1 楼 啊赶 2007-01-16  

相关推荐

    Java调用外部程序命令

    当使用Java调用外部程序时,可能会遇到程序无法正常退出的情况,通常这是由于进程的输入/输出流未被正确处理造成的。 - **解决方案1:** 关闭标准输入流 当外部程序等待标准输入时,如果没有关闭标准输入流,会...

    java中两种方式调用其他.exe可执行程序

    在上面的代码中,我们使用 `Runtime` 类的 `getRuntime` 方法获取当前进程,然后使用 `exec` 方法执行一个外部命令,打开 cmd 命令行并启动 Msconfig.exe 程序。 总结 在 Java 中,我们可以使用 `Desktop` 类和 `...

    java 调用 powershell 并传参 返回

    java 调用 powershell 并传参 返回

    java调用外部文件

    此外,为了安全性和资源管理,避免内存泄漏,最好在调用外部程序后关闭相关流并监控进程状态。这可以通过`Process`对象的`waitFor()`方法实现,等待外部程序完成执行。 总的来说,Java提供了一定的灵活性来调用和...

    windows 系统下启动与结束java的jar包的脚本(包括如何设置进程名称)

    ### Windows系统下启动与结束Java的JAR包的脚本(包括如何设置进程名称) 在Windows环境下管理和控制Java应用程序的启动与停止是一项常见的任务。本文将详细介绍如何编写一个批处理脚本来实现这些功能,并且还会...

    java调用C++ webservice

    - 在Java代码中,实例化存根类,并通过其方法调用C++ Web服务提供的功能。 - 请求会通过HTTP或HTTPS协议发送,通常封装在SOAP消息中。 - C++服务端接收到请求后处理,然后返回响应,同样封装在SOAP消息中。 - ...

    java调用DOS获得系统进程列表

    本篇文章将详细解释如何利用Java语言调用DOS命令来获取Windows系统的进程列表。这不仅适用于Java开发者,也对系统管理员有所帮助。 #### 一、基础知识介绍 在深入探讨具体的实现方法之前,我们首先需要了解一些...

    java调用json参数的webservice

    在探讨Java调用带有JSON参数的WebService之前,我们首先需要了解几个关键的技术概念:Java、JSON以及WebService。 Java是一种广泛使用的编程语言,它具有面向对象、跨平台、多线程以及健壮性等特点。Java在企业级...

    java调用C#接口及所涉及到的架包

    在跨平台应用开发中,有时候我们需要在Java环境中调用C#实现的功能,这通常通过Web服务或者中间件来实现。本文将深入探讨如何在Java中调用C#接口,以及涉及的相关技术栈。 1. **Java与C#的互操作性** Java和C#虽然...

    java调用windows命令

    在Java编程中,有时我们需要在程序中调用Windows系统的命令行操作,例如执行外部程序、系统命令或者进行文件操作。Java提供了Runtime类和Process类来实现这一功能。以下是如何使用Java调用Windows命令行的详细步骤和...

    mysql-connector-java-5.1.40.zip和mysql-connector-java-5.1.10.jar

    MySQL是世界上最受欢迎的开源数据库系统之一,而MySQL Connector/J是MySQL官方提供的用于Java应用程序与MySQL数据库之间连接的驱动程序。本文将深入探讨这两个文件:"mysql-connector-java-5.1.40.zip" 和 "mysql-...

    纯java调用ws-security+CXF实现的webservice安全接口

    本文将深入探讨如何使用CXF框架结合ws-security标准来实现对Java客户端调用Web服务的安全接口。CXF是一个开源的服务框架,它允许开发人员创建和消费各种Web服务,而ws-security(Web Services Security)则是用于...

    DES加密 java与.net可以相互加密解密两种方法

    本文将详细介绍如何在Java和.NET中实现互操作的DES加密解密,并提供两种不同的方法。 **方法一:使用标准库** 1. **Java实现**: - 引用`javax.crypto`包中的`Cipher`、`KeyGenerator`和`SecretKey`类。 - 创建`...

    java调用soap接口案例

    Java调用SOAP(Simple Object Access Protocol)接口是Web服务交互中的常见操作,SOAP是一种基于XML的协议,用于在Web上交换结构化的和类型化的信息。本案例主要关注如何使用Java来实现SOAP请求并获取响应,具体我们...

    QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中

    在QT编程中,有时我们需要与外部应用程序进行交互,例如运行一个独立的可执行文件并将其输出集成到我们的主应用程序窗口中。这可以通过使用QProcess类来实现,它提供了方便的接口来启动、控制以及通信与外部进程。让...

    JAVA 获得控制台的输出信息

    在Java编程语言中,捕获控制台的输出信息是一个常见的需求,尤其是在进行单元测试或调试时,需要收集程序运行过程中的标准输出以便于分析。在提供的代码片段中,展示了一种通过重定向`System.out`流来实现这一目标的...

    C#调用java类、jar包方法

    本篇将详细阐述如何在C#环境中实现对Java类的调用以及使用Java的jar包。 首先,要理解C#与Java之间的互操作性是通过Java Native Interface (JNI) 实现的,但直接使用JNI会非常复杂。为简化这个过程,我们可以借助...

    java获取当前windows进程pid

    功能:获取java进程pid 进程可根据该pid调用exec自杀 注意事项:不能改变PidTool.java所在的包,否则需要重行生成dll。 编译命令中 "-PidTool.dll" 改为 "-FePidTool.dll",我整漏了! 使用方法: 1.javac PidTool...

    java 调用webservice使用HttpClient和XFire两种方式

    在Java开发中,有时我们需要与外部服务进行交互,如发送短信、获取数据等,这时就会用到Web Service。本文将详细介绍如何使用HttpClient和XFire这两种不同的库来调用Web Service,特别是针对短信接口的调用。 首先...

    Java调用应用程序和Dos中的命令

    在Java中,`java.lang.Runtime`类提供了与当前运行时系统交互的方法,其中包括`exec()`方法,该方法允许我们启动一个新的进程并控制其输入和输出流。这对于需要与操作系统交互的任务非常有用。 #### 二、Runtime类...

Global site tag (gtag.js) - Google Analytics