如何捕获从批处理中提取的EXE返回的数据?

时间:2009-11-25 11:10:12

标签: java process batch-file

我有一个需要从java程序调用的批处理文件。批处理文件又调用EXE。 EXE程序将返回我想要处理的数据。如果EXE将数据打印到控制台,则能够按如下方式捕获数据。但是当EXE在完成后返回数据时,我无法捕获它。

ProcessBuilder pb = new ProcessBuilder("foo.bat");
Process p = pb.start();
int exitValue = p.waitFor();
BufferedReader reader;

// System.out.println("Exit Value" + exitValue);
if (exitValue == 0) {
    reader = new BufferedReader(new InputStreamReader(p
            .getInputStream()));
} else {
    reader = new BufferedReader(new InputStreamReader(p
            .getErrorStream()));
}

StringBuffer sb = new StringBuffer();
String temp = reader.readLine();
while (temp != null) {
    sb.append(temp);
    temp = reader.readLine();
}

reader.close();
System.out.println(sb.toString());

我如何捕获从批处理文件执行的EXE返回的数据?

EXE基本上是一个C程序。当我调用C程序时,main方法返回数据,我想要处理它。

2 个答案:

答案 0 :(得分:1)

您是否可以控制脚本? 我会尝试将返回值(这是你想要的吗?)从可执行文件存储到环境变量中。您可能必须将其导出。这是一个关于Java how to handle environment变量的教程。

感谢抖动评论 - 不,它不起作用。我们无法以“全局”方式更改环境变量的值(现在我知道..)

但是,这个想法有点适应:我仍然尝试将返回值存储在全局可访问资源中:只需将返回值发送到文件(exec myapp > result.txt)并从中读取值你的java应用程序中的文件。

答案 1 :(得分:1)

我想我前段时间遇到了同样的问题。先前策略的一个问题是您正在等待进程完成(waitFor)以捕获从其返回的数据。如果进程失败或挂起,您可能会遇到问题。一个更好的方法是这样的:

您应该创建两个线程来使用输入流和进程的错误流,而不依赖于waitFor调用。像这样的东西应该有效:

1.-创建一个包装过程执行的类:

public class ExecutionWrapper {

    private int exitStatus;
    private String[] command;
    private String[] environment;
    private String directory;
    private boolean running;

    private Process process;
    private ExecutionWrapperOutput error;
    private ExecutionWrapperOutput output;

    public ExecutionWrapper(String command, String[] environment, String directory) {
        this.command = new String[] { command };
        this.environment = environment;
        this.directory = directory;
        this.exitStatus = -1;
    }

    public ExecutionWrapper(List<String> command, List<String> environment, String directory) {
        if (command != null)
            this.command = command.toArray(new String[command.size()]);
        if (environment != null)
            this.environment = environment.toArray(new String[environment.size()]);
        this.directory = directory;
        this.exitStatus = -1;
    }

    public void start() {
        try {
            this.process = Runtime.getRuntime().exec(this.command, this.environment, new File(this.directory));
            this.running = true;

            // Error and information messages
            this.error = new ExecutionWrapperOutput(this.process.getErrorStream());
            this.output = new ExecutionWrapperOutput(this.process.getInputStream());

            // Start the messaging threads
            this.error.start();
            this.output.start();

            // Final status
            Runnable runner = new Runnable() {
                public void run() {
                    try {
                        ExecutionWrapper.this.exitStatus = ExecutionWrapper.this.process.waitFor();
                        ExecutionWrapper.this.running = false;
                        ExecutionWrapper.this.process.destroy();
                    } catch (Exception ex) {
                        LoggingUtiles.exception(ex);
                        ExecutionWrapper.this.exitStatus = -1;
                    }
                }
            };
            new Thread(runner).start();

        } catch (Throwable t) {
            LoggingUtiles.exception(t);
        }
    }

    public void stop() {
        this.running = false;
        this.process.destroy();
    }

    public boolean isRunning() {
        return running;
    }

    public int getExitStatus() {
        return exitStatus;
    }

    public String[] getError(boolean clear) {
        return this.error.getLines(clear);
    }

    public String[] getOutput(boolean clear) {
        return this.output.getLines(clear);
    }

    public String[] getCommand() {
        return command;
    }

    public String getDirectory() {
        return directory;
    }

    public void waitFor() {
        try {
            process.waitFor();
        } catch (Throwable t) {
            LoggingUtiles.exception(t);
        }
    }
}

2.-然后,创建ExecutionWrapperOutput类,它处理流程流的输出:

public class ExecutionWrapperOutput extends Thread {

    private InputStream is;

    private List<String> output;

    private Object mutex = new Object();

    ExecutionWrapperOutput(InputStream is) {
        this.is = is;
        this.output = new ArrayList<String>();
    }

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                synchronized (mutex) {
                    output.add(line);
                }
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public String[] getLines(boolean clear) {
        String[] lines = null;
        synchronized (mutex) {
            lines = output.toArray(new String[] {});
            if (clear)
                output.clear();
        }
        return lines;
    }
}

也许这一切对你有用。现在让我,如果它的工作......