几乎所有的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
/
C
/
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程序开发的过程当中,可能涉及到其它的应用程序,借助这种技术,可以很好利用它们,将它们集成到自己的应用当中 |