我正在尝试使用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;
}
答案 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