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

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

你有控制脚本吗? 我会尝试将返回值(这是你想要的?)存储在可执行文件中。 您可能必须将其导出。 这是一个关于如何使用Java 处理环境变量的教程。

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

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

我想我前段时间遇到了同样的问题。 先前策略的一个问题是您正在等待进程完成(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 command, List 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 output; private Object mutex = new Object(); ExecutionWrapperOutput(InputStream is) { this.is = is; this.output = new ArrayList(); } 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; } } 

也许这一切都适合你。 现在让我,如果它的工作……