使用ProcessBuilder使用交互式IO运行java C程序
<>我开发了一个ID/C++软件,使用^ {CD1>}(虽然有很多可用的,但我想要我自己的),可以编译和执行C或C++程序。因此,我尝试了一个简单的程序,使用Process
和ProcessBuilder.
在java中编译和执行C程序
下面是我的简单java程序,它编译并执行C程序:
public class RunProgram {
public static void main(String[] args) throws Exception {
new ProcessBuilder("gcc", "-o", "first", "first.c").start().waitFor(); //To Compile the source file using gcc and wait for compilation
/*
Although I've to handle error-stream but
for now, my assumption is that there is no error
in program.
*/
ProcessBuilder run = new ProcessBuilder("./first");
execute.redirectErrorStream(true);
Process runProcess = run.start();
StreamReader sr = new StreamReader(runProcess.getInputStream());
new Thread(sr).start(); //A new thread to handle output of program .
//rest of coding to provide input using OutputStream of 'runProcess' and to close the stream.
}
}
class StreamReader implements Runnable {
private InputStream reader;
public StreamReader(InputStream inStream) {
reader = inStream;
}
@Override
public void run() {
byte[] buf = new byte[1024];
int size = 0;
try {
while ((size = reader.read(buf)) != -1) {
System.out.println(new String(buf));
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是我的first.c
程序
#include<stdio.h>
int main() {
int a;
int k;
printf("input a: ");
scanf("%d", &a);
for(k = 0; k < a; k++)
printf("k = %d\n", k);
return 0;
}
我想创建交互式IO
控制台,就像大多数IDE或命令终端(Linux基本操作系统中的终端和基于Windows的操作系统中的命令提示符)一样。对于上面的例子:首先,它应该打印“Input a: “
,然后等待提供输入,然后是程序的其余部分但它不会像我想的那样工作,因为它不会打印在scanf
之前出现的printf
语句的结果,直到我可能使用OutputStream
提供输入强>
我在谷歌上搜索我的问题,访问了许多链接,但没有找到解决方案。同时,我发现了this链接,它建议在每个printf
语句之后附加fflush
,或者使用setbuf
或setvbuf
方法(从一些其他子链接)清除缓冲区。但是一个新手(即将学习C)可能不知道fflush
或这些函数,他/她永远不会使用它,因为它在其他IDE中不需要,甚至在终端上也不需要。
如何解决此问题并为我的IDE构建集成控制台
以下是我想要的东西的一瞥:
# 1 楼答案
从上面的评论中可以看出,在这里添加一点关于I/O流缓冲工作原理的解释是有意义的
当调用
printf(3)
之类的函数时,在幕后发生的事情是,数据被写入缓冲区,直到缓冲区填满或发生某种触发。 然后将缓冲区的内容从缓冲区复制到实际输出设备/另一个输出缓冲区。。。 触发器通常遇到行结束(\n
在Linux/Unix下)。 因此,这种缓冲的粗略版本是:现在,如果调用
print
像你永远不会看到
Surthur
出现在stdout
上。 为了将它从缓冲区写入stdout
,您必须flush_buffered
buffered_file.capacity = 1
在上面的示例中)禁用缓冲在您的情况下,您不能显式地调用
fflush(3)
(这就是您所说的需求)。因此,剩下的唯一方法就是禁用缓冲如何做到这一点取决于操作系统,IMHO。 对于Linux,请查看Coreutils包中的
stdbuf(1)
,了解如何为某些外部进程流禁用缓冲# 2 楼答案
在GNU/Linux下,要关闭标准I/O流的缓冲,可以使用^{} 如下所示:
如果要关闭
stderr
和stdin
的缓冲,请添加-e0
和-i0
选项当然,如果您不必依赖外部工具,而是可以在您自己的代码中关闭缓冲,那就更好了-最简单的事情是看一下
stdbuf
的源代码,但我想最终您将不得不使用JNI,然后,我想,我只会坚持stdbuf