【问题标题】:How to capture the data returned from an EXE excuted from a batch?如何捕获从批处理执行的 EXE 返回的数据?
【发布时间】:2010-12-20 06:07:07
【问题描述】:

我有一个需要从 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 方法返回我想要处理的数据。

【问题讨论】:

  • “退回”是什么意思?进程的退出代码?
  • 它不是退出代码。调用EXE时,调用C类main方法,main方法返回数据。

标签: java process batch-file


【解决方案1】:

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

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

但是,这个想法稍加调整就行了:我仍然会尝试将返回值存储在全局可访问资源中:只需将返回值发送到文件 (exec myapp > result.txt) 并从该文件中读取值您的 Java 应用程序。

【讨论】:

  • AFAIK 您无法访问外部程序对环境所做的修改。你确定这行得通吗?你试过了吗。 AFAIK,您只能为要执行的程序设置修改的环境,而不是相反
【解决方案2】:

我想我前段时间也遇到过同样的问题。前一种策略的一个问题是您正在等待进程完成 (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;
    }
}

也许这一切都适合你。如果可行,现在让我...

【讨论】:

    猜你喜欢
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    相关资源
    最近更新 更多