我正在围绕一个简单的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
答案 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);