Java程序中调用Python脚本(兼容Windows与Linux)

一,说明

想实现如下功能,项目后端架构是Spring Boot,某个功能需要调用Python脚本来实现,调用Python脚本的功能要兼容Windows和Linux,即可以运行在Windows和Linux两种平台上。

二,Java代码

// 定义一个线程池来读取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;
    }

三,Python代码

import sys

# 定义一个主函数,作为脚本执行的入口,如果没有主函数,则从第一行开始执行
if __name__ == "__main__":
    # 获取外部输入参数
    param = sys.argv[1]
    print (param)

你可能感兴趣的:(java,python,windows)