需求分析
在编写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()传入代码;