Java调用Python脚本,以Process形式实现

在工作业务中,需要实现用Java调用Python脚本,对比了网上主流的几种实现方式,最终选择以 Process的形式来实现业务需求。

(1)Java代码实现处理方法

/**
 * 运行脚本文件
 *
 * @param scriptPath     脚本位置
 * @param params         请求参数
 */
public void runScript(String scriptPath, List<String> params) {
    long start = System.currentTimeMillis();
    long end = 0L;
    try {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.redirectErrorStream(true);
        List<String> commands = new ArrayList<>();
        commands.add("python");
        commands.add(scriptPath);

        // 参数编码
        log.info("runScript params:" + params);
        params = encodeParams(params);
        commands.addAll(params);
        // 加载命令
        processBuilder.command(commands);
        // 启动进程
        Process process = processBuilder.start();
        String result = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))
                .lines().collect(Collectors.joining());
        log.info("runScript result:" + result);
        Long end = System.currentTimeMillis();
        process.waitFor();
    } catch (Exception e) {
    	log.info("运行脚本文件失败:" + e.getMessage());
        Long end = System.currentTimeMillis();
    }
    log.info("运行时间:" + (end - start));
}

/**
 * 参数编码
 *
 * @param params 参数
 * @return 编码后的参数
 */
private List<String> encodeParams(List<String> params) {
    if (params == null || params.isEmpty()) {
        return params;
    }
    List<String> list = new ArrayList<>();
    for (String param : params) {
        param = param.replace("\"", "@");
        param = new String(param.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
        list.add(param);
    }
    return list;
}

此处参数编码是特殊处理,需要根据实际业务来处理。Java以Process形式实现的就是类似于CMD窗口运行程序,传递的参数是不能有引号的,如果参数比较简单可以省去这一步,如果需要传递JSON等类型的长字符串,那么需要将引号转为其它符号或者字符串,而且需要和Python端约定好,此处我使用了@符号替换了引号。

python返回的参数是python程序执行完成后返回给Java段,返回形式是以窗口输出流的形式返回,也就是在python中使用 print()  或者使用log输出等都会返回给Java。

(2)Python端实现

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

if __name__ == '__main__':
    # 获取Java传递过来的参数,参数是一个列表,第一个是文件位置。后续都是传递过来的参数
    argv = sys.argv
    data = argv[1]
    data = data.replace('@', '"')
    result = json.loads(data)
    print("此处是一个打印。" + str(result))

(3) 编码问题

Java调用Pyhton脚本,一个最主要的问题就是需要处理编码问题,此处我统一使用 UTF-8形式处理。

Java中编码处理如下:

写出编码:

param = new String(param.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);

读取编码:

String result = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)).lines().collect(Collectors.joining());

Python中编码处理如下:

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值