在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:36:22  来源:igfitidea点击:

Capture the output of an external program in JAVA

javaexecoutput

提问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 executorobject (probably DefaultExecutor), create an OutputStreamto whatever stream you wish (i.e a FileOutputStreaminstance may be, or System.out), and:

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

executor.setStreamHandler(new PumpStreamHandler(yourOutputStream));