Posted on 2007-01-14 23:05
網(wǎng)路冷眼@BlogJava 閱讀(4250)
評(píng)論(8) 編輯 收藏 所屬分類:
Java 、
Java SE
幾乎所有的Java 集成開發(fā)環(huán)境都需要調(diào)用外部進(jìn)程進(jìn)行Java程序的構(gòu)建,編譯,運(yùn)行和調(diào)試,Eclipse,NetBeans,JBuilder和Intellij IDLE概莫例外。在執(zhí)行過程中,將提示信息以黑色全部打印在控制臺(tái)里,將異常和錯(cuò)誤以紅色方式打印。以非常醒目交互體驗(yàn)讓程序員遠(yuǎn)離枯燥和乏味。
現(xiàn)在讓我們以Eclipse為例來看看它如何工作的,以揭開它神秘面紗,探究隱藏在后面的秘密。
首先,我們準(zhǔn)備一個(gè)Java 程序,程序如下所示:
import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStreamReader;
/**
*
*
@author
lewhwa
*/
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
"
);
}
}
}
當(dāng)運(yùn)行程序等待輸入時(shí),當(dāng)輸入為“heaven”時(shí)。在Eclipse的控制臺(tái)輸出如圖1所示:
圖1
看來,在Eclipse控制臺(tái)的標(biāo)準(zhǔn)輸出(stdout,System.out)在控制臺(tái)中的顯示為為黑色;標(biāo)準(zhǔn)輸入(stdin,System.in)的顯示為綠色。那么,標(biāo)準(zhǔn)錯(cuò)誤輸出是咋樣的呢?
再次運(yùn)行程序,當(dāng)輸入為“Hell”時(shí)。在Eclipse的控制臺(tái)輸出如圖2所示:
圖2
哦,標(biāo)準(zhǔn)錯(cuò)誤輸出(stderr,System.err)在Eclipse的控制臺(tái)輸出為綠色。
我們知道,在Linux的Shell或者在Windows的Command Prompt窗口執(zhí)行程序,可以在屏幕上打印stdin,stdout,stderr的消息。在Windows上執(zhí)行時(shí),將彈出一個(gè)Command Prompt窗口。在VC下寫過Console程序的應(yīng)該知道,VC在執(zhí)行這些程序時(shí),也馬上彈出一個(gè)這樣的窗口。如果程序執(zhí)行太快,將一閃而過。可是在諸如Eclipse之類的Java IDE里面,并沒有彈出這樣的窗口。我們禁不住要問,它們應(yīng)用了什么技巧?
無論VC,還是像Eclipse這樣的IDE,執(zhí)行程序,實(shí)際上是在自己的進(jìn)程里產(chǎn)生了另外一個(gè)子進(jìn)程,這點(diǎn)誰也比誰強(qiáng)不了多少。但是,VC是直接將運(yùn)行的console程序直接產(chǎn)生一個(gè)Command Prompt窗口。其輸入和輸出均放置到那個(gè)窗口里。而Eclipse則將這些輸入和輸出重定向到了自己的Console里。原來一直在像,Eclipse一定采用了什么動(dòng)態(tài)鏈接庫之類的東東來做這些。
直到有一天使用NetBeans,它完全使用Java,是純Java的。作為IDE,也是將Console程序的輸入和輸出均在IDE 自己Console顯示。這樣,我才明白,一定在Java API里有這樣的功能:能將外部程序的輸入和輸出進(jìn)行攔截,然后在重定向到其它的地方。
重新梳理了一下思路,原來使用過Runtime.exec()這樣的東東,是否所有的一切與之有關(guān)呢?但只是打開Notepad查看一下某個(gè)文本文件之類的應(yīng)用,搞定也就pass了,沒有深究。
仔細(xì)查了查這個(gè)類,終于發(fā)現(xiàn)了這個(gè)秘密。秘密就在Process這個(gè)類。Runtime.getRuntime.exec()執(zhí)行外部程序后,將返回一個(gè)Process對(duì)象。Process有三個(gè)函數(shù)與此有關(guān):
getInputStream();
getErrorStream();
getOutputStream();
到此,我們大概已經(jīng)知道Process是Java IDE完成輸出輸入流攔截的關(guān)鍵所在。下篇,我們將利用此技術(shù)在自己的應(yīng)用中實(shí)現(xiàn)這種技術(shù)。