Java调用GCC实现C代码编译

需求分析

在编写C语言在线考试平台的过程中,有个需求就是在有源代码的情况下,传入input参数,返回C语言执行该input参数后的结果

思路分析

1、ProcessBuilder介绍

通过Java执行系统命令,与cmd中或者终端上一样执行shell命令,最典型的用法就是使用Runtime.getRuntime().exec(command)或者new ProcessBuilder(cmdArray).start()。从JDK1.5开始,官方提供并推荐使用ProcessBuilder类进行shell命令操作。

2、步骤分析

1、首先,通过OutputStream创建后缀名为.c的文件,并将源代码写到该文件中

2、通过ProcessBuilder 调用linux GCC命令,编译.c文件,如果编译出错,则返回错误信息,并结束接下来的操作;

3、如果编译没有出错,则通过ProcessBuilder运行编译后的代码文件,并且传入input参数,

4、将参数返回。

3、代码

(1)、保存源代码到文件

1
public String writeSourceCode(String sourceCode) throws IOException {    FileOutputStream fileOutputStream = new FileOutputStream(filePath);    fileOutputStream.write(sourceCode.getBytes());    fileOutputStream.close();    return filePath;}

(2)、编译文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public String compileCode() throws IOException {    
ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.directory(new File(runPath));
List<String> commands = new ArrayList();
commands.add("gcc");
commands.add("-o");
commands.add("main");
commands.add("main.c");
commands.add("-lm");
processBuilder.command(commands);
Process exec = processBuilder.start();
InputStream inputStream = exec.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String s = null;
StringBuilder stringBuilder = new StringBuilder();
while ((s = reader.readLine()) != null) {
stringBuilder.append(s);
}
return stringBuilder.toString();}

这里,运行命令有两种情况, 如果运行出错,则错错误信息会通过exec的ErrorStream()返回;如果正常运行,ErrorStream()中没有返回值

(3)执行input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public String getOutput(String input) throws IOException, InterruptedException {

ProcessBuilder builder = new ProcessBuilder();
builder.directory(new File(runPath));
builder.redirectErrorStream(true);
builder.command("./main");
String result = "";
Process start = builder.start();

InputStream inputStream = start.getInputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(start.getOutputStream()));
bufferedWriter.write(input);
bufferedWriter.close();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
String tmp = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}
return stringBuilder.toString();
}

这里需要注意的是,如果在命令行中执行代码,是先执行编译后的文件,然后传入input代码,在代码中,可通过process.inputStream()传入代码;


Java调用GCC实现C代码编译
http://yoursite.com/2019/08/26/Java调用GCC实现C代码编译/
作者
yangchen
发布于
2019年8月26日
许可协议