想实现如下功能,项目后端架构是Spring Boot,某个功能需要调用Python脚本来实现,调用Python脚本的功能要兼容Windows和Linux,即可以运行在Windows和Linux两种平台上。
// 定义一个线程池来读取python脚本的执行结果
private static ExecutorService taskPool = new ThreadPoolExecutor(3, 10, 200L, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<>(200),
new ThreadFactoryBuilder().setNamePrefix("thread-python-exec-runner-%d").build());
private void execPythonFile(String path, String params) throws MoyaException {
// 获得操作系统名称
String os = System.getProperty("os.name");
String[] args;
if (os.startsWith("Windows")) {
// 如果当前环境是Windows环境
args = new String[]{"cmd.exe", "/c", "python", path, params};
} else {
// 如果当前环境是Linux环境
args = new String[]{"python", path, params};
}
Process process = null;
try {
// 执行python脚本
process = Runtime.getRuntime().exec(args);
// 错误输出流
InputStream errorStream = process.getErrorStream();
// 正确输出流
InputStream inputStream = process.getInputStream();
// 开线程来读取执行失败的信息
taskPool.submit(() -> {
BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
List<String> list = read(path, reader);
log.info("Python Script execute failed, error message:{}", list);
});
// 开线程来读取执行成功的信息
taskPool.submit(() -> {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
List<String> list = read(path, reader);
log.info("Python Script execute success, successful message:{}", list);
});
// 阻塞进程,等待执行完成
int processResult = process.waitFor();
if (processResult != 0) {
log.error("Python Script error, waitFor is not zero.");
throw new MoyaException("已知威胁流生成失败");
}
} catch (Exception e) {
log.error("python script occur error:{}", e);
throw new MoyaException("已知威胁流生成失败");
} finally {
try {
// 在finally中关闭正确输出流与错误输出流
process.getErrorStream().close();
process.getInputStream().close();
} catch (IOException e) {
log.info("close process stream exception: {}", e);
}
// 执行完成,销毁Process对象
process.destroy();
}
}
/**
* 读取输出流数据,并以数组形式返回读取结果
*
* @param path 路径
* @param reader 缓冲流对象
* @return
*/
private List<String> read(String path, BufferedReader reader) {
List<String> resultList = new ArrayList<>();
String res = "";
while (true) {
try {
// 读取到null值,跳出循环
if ((res = reader.readLine()) == null) break;
} catch (IOException e) {
log.error("reading python file: {} occur exception: {}.", path, e);
}
// 将读取结果放入数组集合中
resultList.add(res);
}
return resultList;
}
import sys
#sys.path.append(os.path.join('/opt/test/demo'))
# 定义一个主函数,作为脚本执行的入口,如果没有主函数,则从第一行开始执行
if __name__ == "__main__":
# 获取外部输入参数
param = sys.argv[1]
print (param)