多次从java代码执行外部程序

时间:2015-06-16 20:14:32

标签: java c++ process

我正在围绕一个简单的C ++程序构建一个java GUI,结果发现我只能执行一次。我希望每次点击按钮都可以运行它,但事实证明它不会让我。

我的研究工作:我做了我最好的来制作一个简化的案例来重现这个错误。以下代码应打印出来"我正在运行"十次。但相反,每当我运行java代码时,它会以不同的数量打印出这个字符串。我在这里做错了什么?

java代码:

import java.io.InputStream;
import java.io.IOException;

public class Main{
    public static void main(String[] args){
        //Declaration of process builder
        ProcessBuilder pb = new ProcessBuilder("./a.out");

        //Loop that should execute a.out 10 times 
        for (int i = 0; i < 10 ; i++) {
            Process p = null;
            String s;
            try{
                //Executing pb (a.out)
                p = pb.start();

                //Catching output of a.out
                InputStream opt = p.getInputStream();
                byte[] buffer = new byte[opt.available()];
                opt.read(buffer, 0, opt.available());
                s = new String(buffer);
            }catch(IOException ex){}

            //Printing the output of a.out
            System.out.println(s);
            p.destroy();
        }
    }
}

C ++程序代码:

#include <iostream>

int main(){
    std::cout<<"I'm running";
}

输出:

I'm running
I'm running



I'm running

1 个答案:

答案 0 :(得分:1)

您正在运行的进程开始异步工作。有时候,c ++程序的打印输出速度还不够快 - 你在初始化或开始编写过程时会终止输出。

完成后,您应该阅读其输出。天真的方法是在创建流程后立即添加对Process.waitFor()的调用 - 这将适用于您在语句中描述的情况。

然而,这种方法存在一个非常大的问题 - 您运行的程序可能会耗尽输出缓冲区,并且必须等到您消耗其输出,因此永远不会终止。因此,如果您运行的程序更复杂,那么您必须编写逻辑,这将执行两者 - 消耗输出并等待程序完成其工作。这是一个例子:

p = pb.start();
InputStream opt = p.getInputStream();
ByteArrayOutputStream boas = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int bytesRead;
while (!p.waitFor(50, TimeUnit.MILLISECONDS)) {
    while ((bytesRead = opt.read(buffer)) > 0) {
        boas.write(buffer, 0, bytesRead);
    }
}
// Reading the final part of the output 
while ((bytesRead = opt.read(buffer)) > 0) {
    boas.write(buffer, 0, bytesRead);
}
s = new String(boas.toByteArray());
System.out.println(s);