在JAVA中捕获外部程序的输出

时间:2013-01-26 22:58:15

标签: java exec output

我正在尝试使用java捕获外部程序的输出,但我不能。

我有代码来显示它,但不是把它放到变量中。

我将使用,例如,sqlplus执行我的oracle代码“into exec.sql” system / orcl @ orcl:用户/密码/数据库名称

public static String test_script () {
        String RESULT="";
        String fileName = "@src\\exec.sql";
        String sqlPath = ".";
        String arg1="system/orcl@orcl";
        String sqlCmd = "sqlplus";


        String arg2   = fileName;
        try {
            String line;
            ProcessBuilder pb = new ProcessBuilder(sqlCmd, arg1, arg2);
            Map<String, String> env = pb.environment();
            env.put("VAR1", arg1);
            env.put("VAR2", arg2);
            pb.directory(new File(sqlPath));
            pb.redirectErrorStream(true);
            Process p = pb.start();
          BufferedReader bri = new BufferedReader
            (new InputStreamReader(p.getInputStream()));

          while ((line = bri.readLine()) != null) {

              RESULT+=line;

          }


          System.out.println("Done.");
        }
        catch (Exception err) {
          err.printStackTrace();
        }
 return RESULT;
    }

2 个答案:

答案 0 :(得分:9)

因为进程将在新线程中执行,所以当你进入while循环时,很可能没有输出或不完整的输出。

Process p = pb.start();  
// process runs in another thread parallel to this one

BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));

// bri may be empty or incomplete.
while ((line = bri.readLine()) != null) {
    RESULT+=line;
}

因此,在尝试与其输出进行交互之前,您需要等待该过程完成。尝试使用Process.waitFor()方法暂停当前线程,直到您的进程有机会完成。

Process p = pb.start();  
p.waitFor();  // wait for process to finish then continue.

BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));

while ((line = bri.readLine()) != null) {
    RESULT+=line;
}

这只是一种简单的方法,您也可以在并行运行时处理流程的输出,但是您需要监控流程的状态,即它是否仍在运行或已完成,以及输出的可用性

答案 1 :(得分:8)

使用Apache Commons Exec,它会让您的生活更轻松。有关基本用法的信息,请查看tutorials。要在获取executor对象(可能是DefaultExecutor)之后读取命令行输出,请为您希望的任何流创建OutputStream(即FileOutputStream实例可能是,或{ {1}})和:

System.out