Java调用外部进程并拦截输入输出流--Java IDE Console解密(上篇)
2007-01-14 23:13
375 查看
几乎所有的Java 集成开发环境都需要调用外部进程进行Java程序的构建,编译,运行和调试,Eclipse,NetBeans,JBuilder和Intellij IDLE概莫例外。在执行过程中,将提示信息以黑色全部打印在控制台里,将异常和错误以红色方式打印。以非常醒目交互体验让程序员远离枯燥和乏味。
现在让我们以Eclipse为例来看看它如何工作的,以揭开它神秘面纱,探究隐藏在后面的秘密。
首先,我们准备一个Java 程序,程序如下所示:
Code
1 import java.io.BufferedReader;
2 import java.io.IOException;
3 import java.io.InputStreamReader;
4
5 /**
6 *
7 * @author lewhwa
8 */
9
public class HelloWorld {
public static void main(String[] args) throws IOException {
System.out.println( " Where will you go to? " );
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(isr);
String name = reader.readLine();
if (name.toUpperCase().equals( " HEAVEN " )) {
System.out.println( " Welcome to heaven! " );
}
if (name.toUpperCase().equals( " HELL " )){
System.err.println( " Go away!here is hell " );
}
}
}
当运行程序等待输入时,当输入为“heaven”时。在Eclipse的控制台输出如图1所示:
图1
看来,在Eclipse控制台的标准输出(stdout,System.out)在控制台中的显示为为黑色;标准输入(stdin,System.in)的显示为绿色。那么,标准错误输出是咋样的呢?
再次运行程序,当输入为“Hell”时。在Eclipse的控制台输出如图2所示:
图2
哦,标准错误输出(stderr,System.err)在Eclipse的控制台输出为绿色。
我们知道,在Linux的Shell或者在Windows的Command Prompt窗口执行程序,可以在屏幕上打印stdin,stdout,stderr的消息。在Windows上执行时,将弹出一个Command Prompt窗口。在VC下写过Console程序的应该知道,VC在执行这些程序时,也马上弹出一个这样的窗口。如果程序执行太快,将一闪而过。可是在诸如Eclipse之类的Java IDE里面,并没有弹出这样的窗口。我们禁不住要问,它们应用了什么技巧?
无论VC,还是像Eclipse这样的IDE,执行程序,实际上是在自己的进程里产生了另外一个子进程,这点谁也比谁强不了多少。但是,VC是直接将运行的console程序直接产生一个Command Prompt窗口。其输入和输出均放置到那个窗口里。而Eclipse则将这些输入和输出重定向到了自己的Console里。原来一直在像,Eclipse一定采用了什么动态链接库之类的东东来做这些。
直到有一天使用NetBeans,它完全使用Java,是纯Java的。作为IDE,也是将Console程序的输入和输出均在IDE 自己Console显示。这样,我才明白,一定在Java API里有这样的功能:能将外部程序的输入和输出进行拦截,然后在重定向到其它的地方。
重新梳理了一下思路,原来使用过Runtime.exec()这样的东东,是否所有的一切与之有关呢?但只是打开Notepad查看一下某个文本文件之类的应用,搞定也就pass了,没有深究。
仔细查了查这个类,终于发现了这个秘密。秘密就在Process这个类。Runtime.getRuntime.exec()执行外部程序后,将返回一个Process对象。Process有三个函数与此有关:
getInputStream();
getErrorStream();
getOutputStream();
到此,我们大概已经知道Process是Java IDE完成输出输入流拦截的关键所在。下篇,我们将利用此技术在自己的应用中实现这种技术。
现在让我们以Eclipse为例来看看它如何工作的,以揭开它神秘面纱,探究隐藏在后面的秘密。
首先,我们准备一个Java 程序,程序如下所示:
Code
1 import java.io.BufferedReader;
2 import java.io.IOException;
3 import java.io.InputStreamReader;
4
5 /**
6 *
7 * @author lewhwa
8 */
9
public class HelloWorld {
public static void main(String[] args) throws IOException {
System.out.println( " Where will you go to? " );
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(isr);
String name = reader.readLine();
if (name.toUpperCase().equals( " HEAVEN " )) {
System.out.println( " Welcome to heaven! " );
}
if (name.toUpperCase().equals( " HELL " )){
System.err.println( " Go away!here is hell " );
}
}
}
当运行程序等待输入时,当输入为“heaven”时。在Eclipse的控制台输出如图1所示:
图1
看来,在Eclipse控制台的标准输出(stdout,System.out)在控制台中的显示为为黑色;标准输入(stdin,System.in)的显示为绿色。那么,标准错误输出是咋样的呢?
再次运行程序,当输入为“Hell”时。在Eclipse的控制台输出如图2所示:
图2
哦,标准错误输出(stderr,System.err)在Eclipse的控制台输出为绿色。
我们知道,在Linux的Shell或者在Windows的Command Prompt窗口执行程序,可以在屏幕上打印stdin,stdout,stderr的消息。在Windows上执行时,将弹出一个Command Prompt窗口。在VC下写过Console程序的应该知道,VC在执行这些程序时,也马上弹出一个这样的窗口。如果程序执行太快,将一闪而过。可是在诸如Eclipse之类的Java IDE里面,并没有弹出这样的窗口。我们禁不住要问,它们应用了什么技巧?
无论VC,还是像Eclipse这样的IDE,执行程序,实际上是在自己的进程里产生了另外一个子进程,这点谁也比谁强不了多少。但是,VC是直接将运行的console程序直接产生一个Command Prompt窗口。其输入和输出均放置到那个窗口里。而Eclipse则将这些输入和输出重定向到了自己的Console里。原来一直在像,Eclipse一定采用了什么动态链接库之类的东东来做这些。
直到有一天使用NetBeans,它完全使用Java,是纯Java的。作为IDE,也是将Console程序的输入和输出均在IDE 自己Console显示。这样,我才明白,一定在Java API里有这样的功能:能将外部程序的输入和输出进行拦截,然后在重定向到其它的地方。
重新梳理了一下思路,原来使用过Runtime.exec()这样的东东,是否所有的一切与之有关呢?但只是打开Notepad查看一下某个文本文件之类的应用,搞定也就pass了,没有深究。
仔细查了查这个类,终于发现了这个秘密。秘密就在Process这个类。Runtime.getRuntime.exec()执行外部程序后,将返回一个Process对象。Process有三个函数与此有关:
getInputStream();
getErrorStream();
getOutputStream();
到此,我们大概已经知道Process是Java IDE完成输出输入流拦截的关键所在。下篇,我们将利用此技术在自己的应用中实现这种技术。
相关文章推荐
- Java调用外部进程并拦截输入输出流--Java IDE Console解密(上篇)
- Java调用外部进程并拦截输入输出流--Java IDE Console解密(下篇)
- Java调用外部进程并拦截输出流--Java IDE Console解密(下篇)
- java 进程控制台输入输出流 (oracle自动升级工具开发源码)
- Java进程调用外部shell脚本
- java程序调用外部进程时不退出
- java调用需要输入的外部可执行程序
- java进程调用外部程序时fork()+exec()分析
- Java进程Runtime、Process、ProcessBuilder调用外部程序
- JAVA调用外部进程时,进程阻塞问题
- Java 调用外部进程
- JAVA调用系统命令或可执行程序--返回一个Runtime运行时对象,然后启动另外一个进程来执行命令
- Java基础学习总结(47)——JAVA输入输出流再回忆
- [Jmeter]通过批处理调用java,java从CSV动态读取登录的用户名和密码,并将其作为参数组合成字符串,写入外部.bat文件,然后通过Java执行这个外部批处理文件
- Java输入输出流
- 浅谈Java的输入输出流
- Java 7源码分析第13篇 - 字节输入输出流(1)
- JAVA I/O操作那些事之输入输出流简介(二)
- Java输入输出流 非常好
- java调用外部exe程序并传参