在 JAVA 中捕获外部程序的输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14542448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Capture the output of an external program in JAVA
提问by AHméd Net
I'm trying to capture output of an external program using java but I can't.
我正在尝试使用 java 捕获外部程序的输出,但我不能。
I have the code to show it, but not to put it into a variable.
我有代码来显示它,但没有把它放到一个变量中。
I will use, for example, sqlplus to execute my oracle code "into exec.sql" system/orcl@orcl : user/password/DB name
例如,我将使用 sqlplus 来执行我的 oracle 代码“进入 exec.sql” system/orcl@orcl : user/password/DB name
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;
}
回答by jsuhre
Because the Process will execute in a new thread it's likely that there is no output or incomplete output available when you come to your while loop.
由于 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;
}
So you need to wait for the process to complete before attempting to interact with it's output. Try using the Process.waitFor()method to pause the current thread until your process has had an opportunity to complete.
因此,在尝试与其输出交互之前,您需要等待该过程完成。尝试使用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;
}
This is only a simple approach you could also process the output of the process while it runs in parallel but then you would need to monitor the status of the process i.e. is it still running or has it completed, and the availability of output.
这只是一种简单的方法,您也可以在进程并行运行时处理它的输出,但随后您需要监视进程的状态,即它是否仍在运行或已完成,以及输出的可用性。
回答by Muhammad Gelbana
Use Apache Commons Exec, it will make your life much easier. Check the tutorialsfor information about basic usage. To read the command line output after obtaining an executor
object (probably DefaultExecutor
), create an OutputStream
to whatever stream you wish (i.e a FileOutputStream
instance may be, or System.out
), and:
使用Apache Commons Exec,它会让你的生活更轻松。查看教程以获取有关基本用法的信息。要在获得executor
对象(可能DefaultExecutor
)后读取命令行输出,请OutputStream
为您希望的任何流创建一个(即FileOutputStream
实例可能是,或System.out
),并且:
executor.setStreamHandler(new PumpStreamHandler(yourOutputStream));