1.编译运行模块
a. 用户提交代码模块:
完成用户代码的输入,只需设置Question类的实例化对象中的code属性,用get和set方法
b.编译运行的整个过程
创建一个Task类:
成员变量有目录、要编译执行的类名、要编译执行的文件名、程序标准输出放置的文件、程序标准错误放置的文件、程序编译出错详细信息放置的文件
public class Task {
// 此处罗列出需要的临时文件(用于进程间通信)文件名约定
// 所有的临时文件要放到这个目录中
private String WORK_DIR;
// 要编译执行的类的名字, 影响到源代码的文件名
private String CLASS = "Solution";
// 要编译执行的文件名
private String CODE;
// 程序标准输出放置的文件
private String STDOUT;
// 程序标准错误放置的文件
private String STDERR;
// 程序编译出错的详细信息放置的文件
private String COMPILE_ERROR;
public Task() {
// 先生成唯一的id, 根据这个 id 来拼装出目录的名字
WORK_DIR = "./tmp/" + UUID.randomUUID().toString() + "/";
// 然后再生成后续的这些文件名
CODE = WORK_DIR + CLASS + ".java";
STDOUT = WORK_DIR + "stdout.txt";
STDERR = WORK_DIR + "stderr.txt";
COMPILE_ERROR = WORK_DIR + "compile_error.txt";
}
成员方法的参数是自己构造的Question类(code:用户在网络上编辑的这段代码),返回值是Answer类(errno、reason、stdout、stderr)
CompileAndRun方法
// Question 表示用户提交的代码
// Answer 表示代码的编译运行结果
public Answer compileAndRun(Question question) throws IOException, InterruptedException {
Answer answer = new Answer();
// 0. 给这些临时文件准备好一个目录
// 判定 WORD_DIR 是否存在. 如果存在就跳过. 不存在就创建目录
File file = new File(WORK_DIR);
if (!file.exists()) {
// 创建对应的目录
file.mkdirs();
}
// 1. 先要准备好需要用到的临时文件
// 要编译的源代码的文件(首先搞这个)
// 编译出错要放进一个文件
// 最终运行的标准输出标准错误也要分别放到文件中
FileUtil.writeFile(CODE, question.