diff --git a/src/main/java/com/sztzjy/financial_bigdata/controller/stu/JupyterController.java b/src/main/java/com/sztzjy/financial_bigdata/controller/stu/JupyterController.java index 071e120..1bc0179 100644 --- a/src/main/java/com/sztzjy/financial_bigdata/controller/stu/JupyterController.java +++ b/src/main/java/com/sztzjy/financial_bigdata/controller/stu/JupyterController.java @@ -38,65 +38,57 @@ public class JupyterController { @ApiOperation("文件校验") @PostMapping("/validate") - @AnonymousAccess public ResultEntity getBlockResources(@RequestBody JSONObject upCodeJson) { - - - //虚拟空间路径 + // 虚拟空间路径 String pyPath = "/usr/local/tianzeProject/financial_bigdata_total/py/"; - //System.out.println(upCodeJson); String pythonCodeUp = upCodeJson.getString("code"); - String pythonCode = ""; + // 替换路径 if (pythonCodeUp.contains("dataResource/")) { pythonCode = pythonCodeUp.replace("dataResource/", pyPath + "dataResource/"); } else { pythonCode = pythonCodeUp; } - if (pythonCode.contains("show")) { - // 创建一个新的 JSONObject + // 如果代码包含 show,进行验证 + if (pythonCode.contains("show")) { JSONObject newJson = new JSONObject(); - newJson.put("code",pythonCode ); // 根据需要进行更改或添加 - + newJson.put("code", pythonCode); // 根据需要进行更改或添加 return validatePythonCodePhoto(newJson); } - try { + // 资源管理部分:声明流和进程 + BufferedReader inputStream = null; + BufferedReader errorStream = null; + Process process = null; + + try { + // 创建临时Python文件 String s = IdUtil.simpleUUID(); - // 写入临时Python文件 String tempPythonFile = "/usr/local/tianzeProject/financial_bigdata_total/py/code/" + s + ".py"; try (PrintWriter out = new PrintWriter(tempPythonFile)) { out.println(pythonCode); } - + // 执行Python代码的Docker命令 String[] command = {"docker", "exec", "pyexe", "python", tempPythonFile}; - // 创建一个新的进程来执行Python代码 - Process process = Runtime.getRuntime().exec(command); - - // 获取进程的输入流 - BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); - - // 获取进程的输出流 - BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); + process = Runtime.getRuntime().exec(command); -// // 向进程的输入流写入Python代码 -// process.getOutputStream().write(pythonCode.getBytes()); -// process.getOutputStream().flush(); -// process.getOutputStream().close(); + // 获取进程的输入流和错误流 + inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); - // 读取Python代码的输出 + // 读取进程输出(正常输出) String line; StringBuilder output = new StringBuilder(); while ((line = inputStream.readLine()) != null) { output.append(line).append("\n"); } - // 读取Python代码的错误信息 + // 读取进程错误输出 StringBuilder errors = new StringBuilder(); while ((line = errorStream.readLine()) != null) { errors.append(line).append("\n"); @@ -105,51 +97,149 @@ public class JupyterController { // 等待进程执行完成 int exitCode = process.waitFor(); + // 删除临时文件 + new File(tempPythonFile).delete(); + + // 根据进程执行结果返回结果 if (exitCode == 0) { - // 执行成功,输出Python代码的结果 return new ResultEntity(HttpStatus.OK, output.toString()); } else { - // 执行失败,输出错误信息 System.err.println("Error executing Python code:\n" + errors.toString()); return new ResultEntity(HttpStatus.OK, errors.toString()); } } catch (IOException | InterruptedException e) { e.printStackTrace(); + return new ResultEntity<>(HttpStatus.BAD_REQUEST); + } finally { + // 确保在finally块中关闭资源 + try { + if (inputStream != null) { + inputStream.close(); + } + if (errorStream != null) { + errorStream.close(); + } + if (process != null) { + process.destroy(); // 销毁进程 + } + } catch (IOException e) { + e.printStackTrace(); // 资源关闭异常处理 + } } - return new ResultEntity<>(HttpStatus.BAD_REQUEST); } +// public ResultEntity getBlockResources(@RequestBody JSONObject upCodeJson) { +// +// +// //虚拟空间路径 +// String pyPath = "/usr/local/tianzeProject/financial_bigdata_total/py/"; +// +// //System.out.println(upCodeJson); +// String pythonCodeUp = upCodeJson.getString("code"); +// +// String pythonCode = ""; +// +// if (pythonCodeUp.contains("dataResource/")) { +// pythonCode = pythonCodeUp.replace("dataResource/", pyPath + "dataResource/"); +// } else { +// pythonCode = pythonCodeUp; +// } +// if (pythonCode.contains("show")) { +// +// // 创建一个新的 JSONObject +// JSONObject newJson = new JSONObject(); +// newJson.put("code",pythonCode ); // 根据需要进行更改或添加 +// +// return validatePythonCodePhoto(newJson); +// } +// try { +// +// String s = IdUtil.simpleUUID(); +// // 写入临时Python文件 +// String tempPythonFile = "/usr/local/tianzeProject/financial_bigdata_total/py/code/" + s + ".py"; +// +// try (PrintWriter out = new PrintWriter(tempPythonFile)) { +// out.println(pythonCode); +// } +// +// +// String[] command = {"docker", "exec", "pyexe", "python", tempPythonFile}; +// // 创建一个新的进程来执行Python代码 +// Process process = Runtime.getRuntime().exec(command); +// +// // 获取进程的输入流 +// BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); +// +// // 获取进程的输出流 +// BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); +// +//// // 向进程的输入流写入Python代码 +//// process.getOutputStream().write(pythonCode.getBytes()); +//// process.getOutputStream().flush(); +//// process.getOutputStream().close(); +// +// // 读取Python代码的输出 +// String line; +// StringBuilder output = new StringBuilder(); +// while ((line = inputStream.readLine()) != null) { +// output.append(line).append("\n"); +// } +// +// // 读取Python代码的错误信息 +// StringBuilder errors = new StringBuilder(); +// while ((line = errorStream.readLine()) != null) { +// errors.append(line).append("\n"); +// } +// +// // 等待进程执行完成 +// int exitCode = process.waitFor(); +// +// if (exitCode == 0) { +// // 执行成功,输出Python代码的结果 +// return new ResultEntity(HttpStatus.OK, output.toString()); +// } else { +// // 执行失败,输出错误信息 +// System.err.println("Error executing Python code:\n" + errors.toString()); +// return new ResultEntity(HttpStatus.OK, errors.toString()); +// } +// } catch (IOException | InterruptedException e) { +// e.printStackTrace(); +// } +// return new ResultEntity<>(HttpStatus.BAD_REQUEST); +// } + + @PostMapping("/validatePythonCodeImg") @ApiOperation("代码检验图片") @AnonymousAccess public ResultEntity validatePythonCodePhoto(@RequestBody JSONObject upCodeJson) { - - - String pythonCode = upCodeJson.getString("code"); - String s = IdUtil.simpleUUID(); List stringList = new ArrayList<>(); + // 资源声明 + PrintWriter out = null; + BufferedReader inputStream = null; + BufferedReader errorStream = null; + Process process = null; + FileInputStream fis = null; + ByteArrayOutputStream baos = null; + try { String pyCode = "/usr/local/tianzeProject/financial_bigdata_total/py/code/"; String pyPath = "/usr/local/tianzeProject/financial_bigdata_total/py/img/"; - // 写入临时Python文件 + // 创建临时Python文件 String tempPythonFile = pyCode + s + ".py"; - // 输出流示例 - PrintWriter out = null; - if (pythonCode.contains("show")) { // 将 pythonCode 按行拆分 String[] lines = pythonCode.split("\\r?\\n"); out = new PrintWriter(tempPythonFile); - int length = lines.length; + int length = lines.length; for (int i = 0; i < lines.length; i++) { - // 跳过注释行 if (lines[i].trim().startsWith("#")) { continue; @@ -164,10 +254,9 @@ public class JupyterController { // 处理最后一行的情况,确保不重复插入 plt.savefig() if (i == length - 1 && lines[i].contains("plt.show()")) { out.println(indent + "plt.savefig('" + plotFile + "')"); // 插入保存语句并保持缩进 - out.println(lines[i]); // 输出原有 plt.show() + out.println(lines[i]); // 输出原有 plt.show() stringList.add(pyPath + imgPathv + ".png"); - continue; } @@ -180,19 +269,16 @@ public class JupyterController { // 在 plt.savefig() 之后输出原来的 plt.show() 语句 out.println(lines[i]); } - out.close(); - - } + out.close(); // 关闭输出流 + } + // 执行Python代码的Docker命令 String[] command = {"docker", "exec", "pyexe", "python", pyCode + s + ".py"}; - // 创建一个新的进程来执行Python代码 - Process process = Runtime.getRuntime().exec(command); + process = Runtime.getRuntime().exec(command); - // 获取进程的输入流 - BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); - - // 获取进程的输出流 - BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); + // 获取进程的输入流和错误流 + inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); // 向进程的输入流写入Python代码 process.getOutputStream().write(pythonCode.getBytes()); @@ -215,27 +301,36 @@ public class JupyterController { // 等待进程执行完成 int exitCode = process.waitFor(); - if (exitCode == 0) { - // 执行成功,输出Python代码的结果 + // 删除临时文件 + new File(pyCode + s + ".py").delete(); + // 根据进程执行结果返回结果 + if (exitCode == 0) { String base64Image = ""; List base64ImageList = new ArrayList<>(); if (!stringList.isEmpty()) { - - for (int i = 0; i < stringList.size(); i++) { - // 读取图片文件并转换为Base64字符串 - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - - try (FileInputStream fis = new FileInputStream(stringList.get(i))) { + for (String imgPath : stringList) { + baos = new ByteArrayOutputStream(); + try { + fis = new FileInputStream(imgPath); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { baos.write(buffer, 0, len); } - + } catch (IOException e) { + e.printStackTrace(); // 资源读取异常 + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); // 关闭文件流异常 + } + } } + base64Image = Base64.encodeBase64String(baos.toByteArray()); base64ImageList.add(base64Image); } @@ -244,22 +339,175 @@ public class JupyterController { } else { return new ResultEntity(HttpStatus.OK, output.toString()); } - - - }else { + } else { // 执行失败,输出错误信息 System.err.println("Error executing Python code:\n" + errors.toString()); return new ResultEntity(HttpStatus.OK, errors.toString()); } - - } catch (IOException | InterruptedException e) { e.printStackTrace(); return new ResultEntity(HttpStatus.BAD_REQUEST, e); + } finally { + // 确保在finally块中关闭所有资源 + try { + if (out != null) { + out.close(); + } + if (inputStream != null) { + inputStream.close(); + } + if (errorStream != null) { + errorStream.close(); + } + if (process != null) { + process.destroy(); // 销毁进程 + } + if (baos != null) { + baos.close(); + } + } catch (IOException e) { + e.printStackTrace(); // 资源关闭异常处理 + } } - } +// public ResultEntity validatePythonCodePhoto(@RequestBody JSONObject upCodeJson) { +// +// +// +// String pythonCode = upCodeJson.getString("code"); +// +// String s = IdUtil.simpleUUID(); +// List stringList = new ArrayList<>(); +// +// try { +// String pyCode = "/usr/local/tianzeProject/financial_bigdata_total/py/code/"; +// String pyPath = "/usr/local/tianzeProject/financial_bigdata_total/py/img/"; +// +// // 写入临时Python文件 +// String tempPythonFile = pyCode + s + ".py"; +// +// // 输出流示例 +// PrintWriter out = null; +// +// if (pythonCode.contains("show")) { +// // 将 pythonCode 按行拆分 +// String[] lines = pythonCode.split("\\r?\\n"); +// out = new PrintWriter(tempPythonFile); +// int length = lines.length; +// +// for (int i = 0; i < lines.length; i++) { +// +// // 跳过注释行 +// if (lines[i].trim().startsWith("#")) { +// continue; +// } +// +// String imgPathv = IdUtil.simpleUUID(); +// String plotFile = pyPath + imgPathv + ".png"; +// +// // 获取当前行的缩进 +// String indent = lines[i].substring(0, lines[i].indexOf(lines[i].trim())); +// +// // 处理最后一行的情况,确保不重复插入 plt.savefig() +// if (i == length - 1 && lines[i].contains("plt.show()")) { +// out.println(indent + "plt.savefig('" + plotFile + "')"); // 插入保存语句并保持缩进 +// out.println(lines[i]); // 输出原有 plt.show() +// +// stringList.add(pyPath + imgPathv + ".png"); +// +// continue; +// } +// +// // 判断是否为 plt.show() 相关的语句 +// if (lines[i].contains("plt.show()") && i != length - 1) { +// out.println(indent + "plt.savefig('" + plotFile + "')"); // 保持缩进 +// stringList.add(pyPath + imgPathv + ".png"); +// } +// +// // 在 plt.savefig() 之后输出原来的 plt.show() 语句 +// out.println(lines[i]); +// } +// out.close(); +// +// } +// +// String[] command = {"docker", "exec", "pyexe", "python", pyCode + s + ".py"}; +// // 创建一个新的进程来执行Python代码 +// Process process = Runtime.getRuntime().exec(command); +// +// // 获取进程的输入流 +// BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); +// +// // 获取进程的输出流 +// BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream())); +// +// // 向进程的输入流写入Python代码 +// process.getOutputStream().write(pythonCode.getBytes()); +// process.getOutputStream().flush(); +// process.getOutputStream().close(); +// +// // 读取Python代码的输出 +// String line; +// StringBuilder output = new StringBuilder(); +// while ((line = inputStream.readLine()) != null) { +// output.append(line).append("\n"); +// } +// +// // 读取Python代码的错误信息 +// StringBuilder errors = new StringBuilder(); +// while ((line = errorStream.readLine()) != null) { +// errors.append(line).append("\n"); +// } +// +// // 等待进程执行完成 +// int exitCode = process.waitFor(); +// +// if (exitCode == 0) { +// // 执行成功,输出Python代码的结果 +// +// String base64Image = ""; +// List base64ImageList = new ArrayList<>(); +// +// if (!stringList.isEmpty()) { +// +// for (int i = 0; i < stringList.size(); i++) { +// // 读取图片文件并转换为Base64字符串 +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// +// +// try (FileInputStream fis = new FileInputStream(stringList.get(i))) { +// byte[] buffer = new byte[1024]; +// int len; +// while ((len = fis.read(buffer)) != -1) { +// baos.write(buffer, 0, len); +// } +// +// } +// base64Image = Base64.encodeBase64String(baos.toByteArray()); +// base64ImageList.add(base64Image); +// } +// +// return new ResultEntity(HttpStatus.OK, output.toString(), base64ImageList); +// } else { +// return new ResultEntity(HttpStatus.OK, output.toString()); +// } +// +// +// }else { +// // 执行失败,输出错误信息 +// System.err.println("Error executing Python code:\n" + errors.toString()); +// return new ResultEntity(HttpStatus.OK, errors.toString()); +// } +// +// +// } catch (IOException | InterruptedException e) { +// e.printStackTrace(); +// return new ResultEntity(HttpStatus.BAD_REQUEST, e); +// } +// +// } + @AnonymousAccess @ApiOperation("python下载生成文件")