在线OJ系统--第一章(实现java编译运行过程)

在线OJ(一)

目标:仿照牛客/leetcode这类在线OJ网站,实现在线做题/判题功能

核心功能

  1. 题目列表页,展示当前系统中所有的题目。
  2. 题目详情页,显示题目的具体要求和代码模板,提供一个编辑框供用户来编辑代码。
  3. 代码的编译/运行/测试功能,能够针对用户提交的代码,进行编译运行,并自动执行测试用例,返回测试结果。

编译模块:给定一个java代码文件(只考虑单个文件的情况,不考虑多文件复杂工程)能够通过代码来控制jdk进行编译运行。通过借助Runtime这个对象,可以创建出一个子进程,并且让子进程来执行一个相关的命令。编译:javac,运行:java

进程与线程

进程是资源分配的基本单位。

线程是CPU调度和执行的基本单位

线程相比于进程的优势:

1.线程更轻量,创建一个线程开销比创建进程低很多;销毁一个线程的开销也比销毁一个进程开销低很多。

2.同一个进程中的所有线程共享着一些数据。

线程相比于进程的劣势:

1.线程代码编写更困难,涉及线程安全。

2.线程代码调试也更加困难。

3.对于程序的稳定性也就提出了更高要求。

CommandUtil

如何利用子进程来执行命令?接下来就是对CommandUtil的讲解,其本质就是利用了jdk的Runtime对象。

在这里插入图片描述

exec方法干了两件事:1.创建子进程。2.进程程序替换

在这里插入图片描述

这里的运行结果实际上是父进程的输出结果,那么如果我们想要获取子进程的输出结果就需要使用到“重定向”功能,把进程输出的内容写到指定的文件中。具体实现:实现重定向,需要先获取到子进程对象,借助exec返回的Process对象,通过标准输入输出来重定向保存子进程输出结果。

在这里插入图片描述

执行结果发现:文件是有了,但是内容没有,为什么?因为一个命令的输出内容也可能是通过标准错误来打印的。操作系统中的任何一个进程,启动的时候都会自动打开三个文件:标准输入、标准输出、标准错误。并通过文件管理的方式,将其组织起来。我们只需要将上图第三步复制,修改为标准错误重定向就好了(process.getErrStream())。

在这里插入图片描述

执行结果:

首先,生成了两个对应的文件。

在这里插入图片描述

第二,在stderrFile.txt文件中可以看到内容,也就是我们在cmd中直接输入javac的内容。

在这里插入图片描述

当然,我们还需要考虑一件事,本身预期目标是用父进程中的run方法来控制子进程执行功能。在执行run的过程中,子进程也在执行。当run执行结束之后,也必须确保子进程也已经执行完了。但是此时这个代码中,子进程和父进程之间是并发关系,谁先执行完时无法确定的,为了能够明确让子进程先执行完,就需要让父进程进行等待。

在这里插入图片描述

CommandUtil代码

import java.io.*;

// 借助这个类,让java代码能够去执行一个具体的指令
// 例如:javac Test.java
public class CommandUtil {
   
    //cmd 表示要执行的命令
    //stdoutFile 表示标准输出结果重定向到哪个文件中,如果为null表示不需要重定向
    //stderrFile 表示标准错误结果重定向到哪个文件中。
    public static int run(String cmd,String stdoutFile,String stderrFile) throws IOException, InterruptedException {
   
        //1.获取Runtime对象  ,Runtime对象是一个单例的
        Runtime runtime = Runtime.getRuntime();
        //2.通过runtime对象中的exec方法来执行一个指令。
        // 相当于在命令行中输入了命令
        // 获取exec返回的Process对象
        Process process = runtime.exec(cmd);
        //3.通过标准输入输出对输出结果进行重定向保存
        if(stdoutFile != null){
   
            //进程的标准输出中的结果就可以通过这个InputStream来获取
            InputStream stdoutFrom = process.getInputStream();
            OutputStream stdoutTo = new FileOutputStream(stdoutFile);
            int ch = -1;
            while((ch = stdoutFrom.read()) != -1){
   
                stdoutTo.write(ch);
            }
            stdoutFrom.close();
            stdoutTo.close();
        }
        //4.针对标准错误也进行重定向
        if(stderrFile != null){
   
            InputStream stderrFrom = process.getErrorStream();
            OutputStream stderrTo = new FileOutputStream(stderrFile);
            int ch = -
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值