当前位置:   article > 正文

Java调用Python脚本,以Process形式实现_java process process 执行python 语句打印

java process process 执行python 语句打印

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

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

  1. /**
  2. * 运行脚本文件
  3. *
  4. * @param scriptPath 脚本位置
  5. * @param params 请求参数
  6. */
  7. public void runScript(String scriptPath, List<String> params) {
  8. long start = System.currentTimeMillis();
  9. long end = 0L;
  10. try {
  11. ProcessBuilder processBuilder = new ProcessBuilder();
  12. processBuilder.redirectErrorStream(true);
  13. List<String> commands = new ArrayList<>();
  14. commands.add("python");
  15. commands.add(scriptPath);
  16. // 参数编码
  17. log.info("runScript params:" + params);
  18. params = encodeParams(params);
  19. commands.addAll(params);
  20. // 加载命令
  21. processBuilder.command(commands);
  22. // 启动进程
  23. Process process = processBuilder.start();
  24. String result = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))
  25. .lines().collect(Collectors.joining());
  26. log.info("runScript result:" + result);
  27. Long end = System.currentTimeMillis();
  28. process.waitFor();
  29. } catch (Exception e) {
  30. log.info("运行脚本文件失败:" + e.getMessage());
  31. Long end = System.currentTimeMillis();
  32. }
  33. log.info("运行时间:" + (end - start));
  34. }
  35. /**
  36. * 参数编码
  37. *
  38. * @param params 参数
  39. * @return 编码后的参数
  40. */
  41. private List<String> encodeParams(List<String> params) {
  42. if (params == null || params.isEmpty()) {
  43. return params;
  44. }
  45. List<String> list = new ArrayList<>();
  46. for (String param : params) {
  47. param = param.replace("\"", "@");
  48. param = new String(param.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
  49. list.add(param);
  50. }
  51. return list;
  52. }

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

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

(2)Python端实现

  1. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
  2. if __name__ == '__main__':
  3. # 获取Java传递过来的参数,参数是一个列表,第一个是文件位置。后续都是传递过来的参数
  4. argv = sys.argv
  5. data = argv[1]
  6. data = data.replace('@', '"')
  7. result = json.loads(data)
  8. 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')
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/478531
推荐阅读
相关标签
  

闽ICP备14008679号