8

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

我有显示它的代码,但没有将它放入变量中。

例如,我将使用 sqlplus 执行我的 oracle 代码“进入 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;
    }
4

2 回答 2

10

因为 Process 将在新线程中执行,所以当您进入 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;
}

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

于 2013-01-26T23:39:16.877 回答
8

使用Apache Commons Exec,它会让你的生活更轻松。查看教程以获取有关基本用法的信息。要在获取executor对象(可能是)后读取命令行输出,请为您希望的任何流DefaultExecutor创建一个(即实例可能是,或),并且:OutputStreamFileOutputStreamSystem.out

executor.setStreamHandler(new PumpStreamHandler(yourOutputStream));
于 2013-01-26T23:00:23.607 回答