Java调用外部程序的例子

    Java调用外部应用程序都是通过“Runtime.getRuntime().exec()”来实现的。但是,因调用的内容不同,而需要额外处理的内容也不同。我就说一下调用BAT和SHELL的情况。

1.如何在Windows下调用BAT。

由于BAT脚本里的命令大部分是windows的内部命令,所以要能正常执行,必须要command.COM(Win95、Win98)或CMD.EXE(XP、NT)的支持。所以我们必须在Runtime.getRuntime().exec()执行的内容前增加“CMD.EXE /C”表示启动一个CMD的终端执行。

2.如何在Linux下调用SHELL。

如果直接在Linux下通过“Runtime.getRuntime().exec()”来执行命令,常常会遇到调用执行的进程无响应,出现这个原因是Linux终端执行的命令处于等待输入状态,所以外部调用的进程无响应。解决的办法就是将系统的标准输入一直打印出来。见下列代码:

// read buffer of parent process' input stream
            final BufferedReader reader = new BufferedReader(
                    new InputStreamReader(System.in));
            tIn = new Thread() {
                public void run() {
                    try {
                        while (true) {
                            outputStream.write((reader.readLine() + "\n")
                                    .getBytes());
                            outputStream.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }; 

 

说完了上述两部分内容,我把完整实现代码贴上来吧。 这里,提供了一个调用方法,及一个用于输出信息和错误的线程类。

     public void invoke(ExternalProgramTask task) throws IOException,
            InterruptedException {
        List<String> cmdArgs = new ArrayList<String>();
        final boolean osIsWindows = osIsWindows();
        int i = 0;
        if (osIsWindows) {
            cmdArgs.add(i++, "cmd.exe");
            cmdArgs.add(i++, "/C");
        } else {
            
        }
        for (String str : task.getParameter()) {
            cmdArgs.add(i++, str);
        }
        log(task, Level.INFO, cmdArgs, null);
        Process child = Runtime.getRuntime().exec(
                cmdArgs.toArray(new String[] {}));

        // any output?
        Thread tOut = new StreamGobbler(child.getInputStream(),
                StreamGobbler.INFO);
        // any error message?
        Thread tErr = new StreamGobbler(child.getErrorStream(),
                StreamGobbler.ERROR);

        // any input?
        final OutputStream outputStream = child.getOutputStream();
        Thread tIn = null;
        if (!osIsWindows) {
            // read buffer of parent process' input stream
            final BufferedReader reader = new BufferedReader(
                    new InputStreamReader(System.in));
            tIn = new Thread() {
                public void run() {
                    try {
                        while (true) {
                            outputStream.write((reader.readLine() + "\n")
                                    .getBytes());
                            outputStream.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
        }
        // kick them off
        tErr.start();
        if (tIn != null)
            tIn.start();
        tOut.start();
        int result = child.waitFor();
        outputStream.close();
        if (result == 0) {
            log(task, Level.INFO, "SUCCESS!", null);
        } else {
            log(task, Level.SEVERE, "FAILED!", null);
        }
    }

    class StreamGobbler extends Thread {
        static final int INFO = 0;

        static final int ERROR = 1;

        private final InputStream is;
        private final int type;
        private final OutputStream os;

        private volatile boolean isStop = false;

        StreamGobbler(InputStream is, int type) {
            this(is, type, null);
        }

        StreamGobbler(InputStream is, int type, OutputStream redirect) {
            this.is = is;
            this.type = type;
            this.os = redirect;
        }

        public void run() {
            try {
                PrintWriter pw = null;
                if (os != null)
                    pw = new PrintWriter(os);

                InputStreamReader isr = null;
                try {
                    isr = new InputStreamReader(is, System.getProperty(
                            "sun.jnu.encoding", "UTF8"));
                } catch (UnsupportedEncodingException e) {
                    log(task, Level.SEVERE, e.getLocalizedMessage(), e);
                }
                if (isr == null) {
                    log(task, Level.SEVERE,
                            "InputStreamReader is null,return.", null);
                    return;
                }
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                int lineNumber = 0;
                while ((!isStop) && (line = br.readLine()) != null) {
                    if (pw != null)
                        pw.println(line);
                    if (type == INFO) {
                        System.out.println(" INFO>" + lineNumber + "." + line);
                        log(task, Level.INFO, lineNumber + "." + line, null);
                    } else {
                        System.err.println(" ERROR>" + lineNumber + "." + line);
                        log(task, Level.SEVERE, lineNumber + "." + line, null);
                    }
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    lineNumber++;
                }
                if (pw != null)
                    pw.flush();
            } catch (IOException ioe) {
                ioe.printStackTrace();
                log(task, Level.SEVERE, ioe.getLocalizedMessage(), ioe);
            }
        }

        public void stopThread() {
            isStop = true;
        }
    }

posted @ 2009-11-03 10:28  Java农场  阅读(640)  评论(0编辑  收藏  举报