最近需要用Java写一个调用外部应用的程序,也就是说要在Java程序中调用外部应用(.exe)。
起初直接使用“Runtime.getRuntime().exec(String command, String[] env, File dir)”这个函数调用,但是程序老是阻塞,无法正常执行。
后来采用了读入InputStream的方法希望解决问题,可惜还是失败了,程序依然阻塞,无法执行完毕。
百般无奈之下上网搜了搜,归结起来问题就处在异常流和输入流上。网上所列举的方法,或者首先读入异常流,再读入输入流,或者启不同的线程,分别读取异常流和输入流。
经过自己的实验,在jdk1.6.0和Windows XP SP3下测试的结果,只有启两个线程分别读不通的流,程序才可以顺利执行。
代码大致如下:
- public class Solver {
- public void solve() {
- // 构造命令行 cmd /c 可以调用一个普通的.exe文件,注意目录位置
- String cmd = "cmd /c d://test";
- // 设置工作目录
- File workDir = new File("c://");
- try {
- Process process = Runtime.getRuntime().exec(cmd, null, workDir);
- // 读取错误流和正常流的输入,否则会阻塞,不能正确获得结果
- InputStream stderr = process.getErrorStream();
- getInputData(stderr, "solver Error>>>");
- InputStream inpbuildtar = process.getInputStream();
- getInputData(inpbuildtar, "solver Info>>>");
- int progEnd = process.waitFor();
- if (progEnd != 0) {
- throw new RuntimeException("Solver Error");
- }
- } catch (Exception e) {
-
- }
- }
- /**
- * 读流中数据
- *
- * @param inputStream
- * @param prefix
- */
- private void getInputData(final InputStream inputStream, final String prefix) {
- new Thread() {
- public void run() {
- try {
- StringBuilder builder = new StringBuilder();
- int c = inputStream.read();
- while (c >= 0) {
- builder.append((char) c);
- c = inputStream.read();
- }
- } catch (IOException e) {
- }
- }
- }.start();
- }
- }

本文介绍了一种解决Java程序调用外部.EXE文件时出现阻塞问题的方法。通过创建两个独立线程分别读取标准输出流和错误输出流,确保了程序能够顺利执行并获取完整的输出结果。
420

被折叠的 条评论
为什么被折叠?



