记一次OJ在线代码编辑器(代码编译+运行,C、C++、Java)

如何在SpringBoot+Vue的项目中实现在线代码编译及执行(支持编译运行C、C++、Java),研究了一天,真实能用,下面直接上源码!!!

——————————————————————————————————————————

一、后端(直接接收字符串进行代码编译)

(1)C编译执行方法(直接调用,传入字符串即可完成编译)

package complier.complier_c;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

import complier.util.FileUtil;

/**
 * C编译器
 * @author tpw
 *
 */
public class CComplier {
	
	private final static String CplusplusFILEPATH=System.getProperty("user.dir") + "\\cCode\\";
	private final static String CplusplusFILENAME="main.c";
	private final static String CplusplusEXE="main.exe";
	
	private String inputData; //输入数据
	private String outputData; //输出数据
	private String errorMsg; //程序错误信息
	
	public CComplier() {
		this.inputData="";
		this.errorMsg="";
	}
	public CComplier(String inputData) {
		super();
		this.inputData = inputData;
		this.errorMsg="";
	}
	public CComplier(String inputData, String outputData, String errorMsg) {
		super();
		this.inputData = inputData;
		this.outputData = outputData;
		this.errorMsg = errorMsg;
	}
	
	public void complier() {
		// 这里调用执行写入工具类,其他两个好像没写,这里给出个demo
		FileUtil.writeFile(inputData,CplusplusFILEPATH+CplusplusFILENAME);
		// 进入c代码存放文件夹
		// 使用gcc命令来编译c文件,来生成一个exe文件
		// 直接运行exe文件

		// cmd命令:cd /d d:\javaworkspace\complier\cCode
		// cmd命令:gcc main.cpp
		// cmd命令:main.exe
		StringBuffer errorInfo = new StringBuffer();
		Process p=null;
		try {
			//1.编译C++文件
			p = Runtime.getRuntime().exec("gcc "+CplusplusFILEPATH+CplusplusFILENAME+" -o "+CplusplusFILEPATH+"main");
			// 获取进程的错误流
			final InputStream is1 = p.getErrorStream();
			// 开一个线程,读标准错误流
			new Thread() {
				public void run() {
					try {
						BufferedReader br1 = new BufferedReader(new InputStreamReader(is1,Charset.forName("GBK")));
						String line1 = null;
						while ((line1 = br1.readLine()) != null) {
							if (line1 != null) {
								errorInfo.append(line1 + "\n");
							}
						}
						if(!errorInfo.toString().equals("")) {
							errorMsg=errorInfo.toString();
						}
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							is1.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();
			p.waitFor();
			p.destroy();
			//2.如果没错的话就运行exe文件
			if (errorInfo.toString().equals("")) {
				try {
					Process process = Runtime.getRuntime().exec(CplusplusFILEPATH+CplusplusEXE);
					BufferedWriter bout = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
			        bout.write(this.inputData);
			        bout.close();
					BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(),Charset.forName("GBK")));
					String line = null;
					StringBuffer b = new StringBuffer();
					while ((line = br.readLine()) != null) {
						b.append(line + "\n");
					}
					this.outputData=b.toString();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			try {
				p.getErrorStream().close();
				p.getInputStream().close();
				p.getOutputStream().close();
			} catch (Exception ee) {
				ee.printStackTrace();
			}
		}
	}
	
	public String getInputData() {
		return inputData;
	}
	public void setInputData(String inputData) {
		this.inputData = inputData;
	}
	public String getOutputData() {
		return outputData;
	}
	public void setOutputData(String outputData) {
		this.outputData = outputData;
	}
	public String getErrorMsg() {
		return errorMsg;
	}
	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
}

(2)C++编译执行方法(直接调用,传入字符串即可完成编译)

package complier.complier_cplusplus;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

/**
 * C++编译器
 * @author tpw
 *
 */
public class CplusplusComplier {
	
	private final static String CplusplusFILEPATH=System.getProperty("user.dir") + "\\c++Code\\";
	private final static String CplusplusFILENAME="main.cpp";
	private final static String CplusplusEXE="main.exe";
	
	private String inputData; //输入数据
	private String outputData; //输出数据
	private String errorMsg; //程序错误信息
	
	public CplusplusComplier() {
		this.inputData="";
		this.errorMsg="";
	}
	public CplusplusComplier(String inputData) {
		super();
		this.inputData = inputData;
		this.errorMsg="";
	}
	public CplusplusComplier(String inputData, String outputData, String errorMsg) {
		super();
		this.inputData = inputData;
		this.outputData = outputData;
		this.errorMsg = errorMsg;
	}
	
	public void complier() {
		// 进入c++代码存放文件夹
		// 使用g++命令来编译c++文件,来生成一个exe文件
		// 直接运行exe文件

		// cmd命令:cd /d d:\javaworkspace\complier\c++Code
		// cmd命令:g++ main.cpp
		// cmd命令:main.exe
		StringBuffer errorInfo = new StringBuffer();
		Process p=null;
		try {
			//1.编译C++文件
			p = Runtime.getRuntime().exec("g++ "+CplusplusFILEPATH+CplusplusFILENAME+" -o "+CplusplusFILEPATH+"main");
			// 获取进程的错误流
			final InputStream is1 = p.getErrorStream();
			// 开一个线程,读标准错误流
			new Thread() {
				public void run() {
					try {
						BufferedReader br1 = new BufferedReader(new InputStreamReader(is1,Charset.forName("GBK")));
						String line1 = null;
						while ((line1 = br1.readLine()) != null) {
							if (line1 != null) {
								errorInfo.append(line1 + "\n");
							}
						}
						if(!errorInfo.toString().equals("")) {
							errorMsg=errorInfo.toString();
						}
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							is1.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();
			p.waitFor();
			p.destroy();
			//2.如果没错的话就运行exe文件
			if (errorInfo.toString().equals("")) {
				try {
					Process process = Runtime.getRuntime().exec(CplusplusFILEPATH+CplusplusEXE);
					BufferedWriter bout = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
			        bout.write(this.inputData);
			        bout.close();
					BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(),Charset.forName("GBK")));
					String line = null;
					StringBuffer b = new StringBuffer();
					while ((line = br.readLine()) != null) {
						b.append(line + "\n");
					}
					this.outputData=b.toString();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			try {
				p.getErrorStream().close();
				p.getInputStream().close();
				p.getOutputStream().close();
			} catch (Exception ee) {
				ee.printStackTrace();
			}
		}
	}
	
	public String getInputData() {
		return inputData;
	}
	public void setInputData(String inputData) {
		this.inputData = inputData;
	}
	public String getOutputData() {
		return outputData;
	}
	public void setOutputData(String outputData) {
		this.outputData = outputData;
	}
	public String getErrorMsg() {
		return errorMsg;
	}
	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
}

(3)Java编译执行方法(直接调用,传入字符串即可完成编译)

package complier.complier_java;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

/**
 * java编译器
 * @author tpw
 *
 */
public class JavaComplier {
	
	private final static String jAVAFILEPATH=System.getProperty("user.dir") + "\\javaCode";
	private final static String JAVAFILENAME="Main.java";
	private final static String jAVAFILECLASNAME="Main";
	
	private String inputData; //输入数据
	private String outputData; //输出数据
	private String errorMsg; //程序错误信息
	
	public JavaComplier() {
		this.inputData="";
		this.errorMsg="";
	}
	public JavaComplier(String inputData) {
		super();
		this.inputData = inputData;
		this.errorMsg="";
	}
	public JavaComplier(String inputData, String outputData, String errorMsg) {
		super();
		this.inputData = inputData;
		this.outputData = outputData;
		this.errorMsg = errorMsg;
	}
	
	public void complier() {
		// 进入java代码存放文件夹
		// 使用javac命令来编译java文件,来生成一个class文件
		// 使用java命令来运行类

		// cmd命令:cd /d d:\javaworkspace\complier\javaCode
		// cmd命令:javac Main.java
		// cmd命令:java Main
		StringBuffer errorInfo = new StringBuffer();
		Process p=null;
		try {
			//1.编译java文件
			p = Runtime.getRuntime().exec("javac "+JAVAFILENAME, null, new File(jAVAFILEPATH));
			// 获取进程的错误流
			final InputStream is1 = p.getErrorStream();
			// 开一个线程,读标准错误流
			new Thread() {
				public void run() {
					try {
						BufferedReader br1 = new BufferedReader(new InputStreamReader(is1,Charset.forName("GBK")));
						String line1 = null;
						while ((line1 = br1.readLine()) != null) {
							if (line1 != null) {
								errorInfo.append(line1 + "\n");
							}
						}
						if(!errorInfo.toString().equals("")) {
							errorMsg=errorInfo.toString();
						}
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							is1.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();
			p.waitFor();
			p.destroy();
			//2.如果没错的话就运行java文件
			if (errorInfo.toString().equals("")) {
				try {
					Process process = Runtime.getRuntime().exec("java "+jAVAFILECLASNAME, null, new File(jAVAFILEPATH));
					BufferedWriter bout = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
			        bout.write(this.inputData);
			        bout.close();
					BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(),Charset.forName("GBK")));
					String line = null;
					StringBuffer b = new StringBuffer();
					while ((line = br.readLine()) != null) {
						b.append(line + "\n");
					}
					this.outputData=b.toString();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			try {
				p.getErrorStream().close();
				p.getInputStream().close();
				p.getOutputStream().close();
			} catch (Exception ee) {
				ee.printStackTrace();
			}
		}
	}
	
	public String getInputData() {
		return inputData;
	}
	public void setInputData(String inputData) {
		this.inputData = inputData;
	}
	public String getOutputData() {
		return outputData;
	}
	public void setOutputData(String outputData) {
		this.outputData = outputData;
	}
	public String getErrorMsg() {
		return errorMsg;
	}
	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
}

(4)字符串写入工具类(直接调用,传入字符串即可完成写入)

package complier.util;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class FileUtil {

	public static void writeFile(String content,String filePath) {
         try {
        	 BufferedWriter out = new BufferedWriter(new FileWriter(filePath));
        	 out.write(content);
        	 out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}    
	}
}

(5)测试调用Demo

package complier.complier_java;

public class Test {
	
	public static void main(String[] args) {
        // 这里调用的Java编译,其他类同
		JavaComplier javaComplier=new JavaComplier("Hello!!");
		javaComplier.complier();
		String proError=javaComplier.getErrorMsg();
		if(!proError.equals("")) {
			System.err.println(proError);
		}else {
			System.out.println(javaComplier.getOutputData());
		}
	}
}


二、前端(输入字符串,简单的直接输入框,复杂点就用ACE插件或者其他,此案例使用的ACE)

js引入方式可以采取以下方式,推荐本地下载包引入:

        在线js引入举例(这两个是可以用的):     

     
     

        本地js引入举例:     

     
 






效果截图 :

记一次OJ在线代码编辑器(代码编译+运行,C、C++、Java)_第1张图片

三、编译执行代码还需要在项目的src同级目录下创建对应的编译文件夹,用于接收字符串写入并执行。下面放出目录截图,直接用记事本创建并更改扩展名即可,文件里面的内容都是空的。

记一次OJ在线代码编辑器(代码编译+运行,C、C++、Java)_第2张图片

四、此项目总体截图

输入代码(C):

记一次OJ在线代码编辑器(代码编译+运行,C、C++、Java)_第3张图片

代码执行结果:

你可能感兴趣的:(java,开发语言,c语言,html,javascript)