java项目调用外部python脚本,windows和liunx通用
在java项目开发中,遇到了需要使用python脚本的情景,通过摸索整理了一下方法
package com.demo.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CalculationAndHandle {
private final static Logger logger = LoggerFactory.getLogger(CalculationAndHandle.class);
/**
* 计算
* @param prefix
* @param filename
* @param filepath
* @return
*/
public Boolean calculationByPython(String prefix, String filename, String filepath) throws IOException{
Boolean result = true;
Process pr = null;
BufferedReader in = null;
try{
logger.info("开始执行脚本进行计算!!!");
//java调用外部程序,指定执行前缀、文件名、文件执行路径
pr = Runtime.getRuntime().exec(prefix + " " + filename, null , new File(filepath));
//建立一个BufferedReader对象,从字符输入流中读取文本即读取python脚本
readStreamInfo(pr.getInputStream(), pr.getErrorStream());
//in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
//等待进程运行完成再向下执行,0为成功,1为操作不允许,2为文件路径问题
int r2 = pr.waitFor();
if (r2 == 0) {
System.out.println("子进程正常完成");
} else {
System.out.println("子进程异常结束");
}
logger.info("statue======="+r2);
if(r2 != 0){
result = false;
}
logger.info("脚本计算结束!!!");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e){
e.printStackTrace();
} finally {
if(null != pr) {
pr.getInputStream().close();
pr.getOutputStream().close();
pr.getErrorStream().close();
pr.destroy();
}
}
return result;
}
/**
* 读取RunTime.exec运行子进程的输入流 和 异常流
* @param inputStreams 输入流
*/
public static void readStreamInfo(InputStream... inputStreams){
ExecutorService executorService = Executors.newFixedThreadPool(inputStreams.length);
for (InputStream in : inputStreams) {
executorService.execute(new MyThread (in));
}
executorService.shutdown();
}
}
需要注意的是,我这里调用的python环境是3.8.0版本,会返回标识状态(0为成功,1为操作不允许,2为文件路径问题)。说简单一些,只要是非0就是执行失败,在后台日志可以打印出对应的执行日志,前提是python脚本可以输出,我认为该方法在winodws环境下的核心,其实就是cmd跑的,liunx不太熟悉还不知道。该方法windows、liunx通用。