springboot中测试python脚本:ProcessBuilder

目录

一.添加Jython依赖

二.使用步骤

[1. 创建 ProcessBuilder 实例](#1. 创建 ProcessBuilder 实例)

[2. 设置工作目录(可选)](#2. 设置工作目录(可选))

[3. 合并错误流(可选)](#3. 合并错误流(可选))

[4. 启动进程](#4. 启动进程)

[5. 处理输入输出流](#5. 处理输入输出流)

[6. 等待进程完成](#6. 等待进程完成)

7.完整案例

三.注意事项


ProcessBuilder是jdk提供的脚本执行工具类,无论是python文件还是shell脚本还是其他的指令,都可以通过此类来执行,我们来看看它是如何调用python脚本的。

ProcessBuilder 是 Java 提供的一个用于创建操作系统进程的类,它使得启动和管理外部进程变得更加简单和灵活。以下是一个详细的教程,帮助你理解如何在 Java 中使用 ProcessBuilder

一.添加Jython依赖

复制代码
<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.7.2</version> <!-- 确认版本号是最新的 -->
</dependency>

二.使用步骤

1. 创建 ProcessBuilder 实例

首先,你需要创建一个 ProcessBuilder 的实例,并指定要执行的命令及其参数。命令可以是一个简单的字符串数组,其中第一个元素是命令名称,后续元素是该命令的参数。

java 复制代码
List<String> command = Arrays.asList("python3", "path/to/your_script.py", "arg1", "arg2");
ProcessBuilder processBuilder = new ProcessBuilder(command);
2. 设置工作目录(可选)

你可以为这个进程设置一个工作目录,如果未指定,默认的工作目录将是当前Java进程的工作目录。

java 复制代码
processBuilder.directory(new File("/path/to/working/directory"));
3. 合并错误流(可选)

默认情况下,标准输出和标准错误是分开的。如果你希望将它们合并到一起处理,可以调用 redirectErrorStream(true) 方法。

java 复制代码
processBuilder.redirectErrorStream(true);
4. 启动进程

通过调用 start() 方法来启动进程,并获得一个 Process 对象,你可以使用这个对象与新进程进行交互。

java 复制代码
Process process = processBuilder.start();
5. 处理输入输出流

为了从子进程中获取输出或向子进程发送输入,你需要处理 Process 对象的标准输入、输出和错误流。

java 复制代码
// 获取子进程的输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF-8));
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line); // 或者做其他处理
}

// 如果需要发送数据到子进程的标准输入
OutputStream out = process.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF-8);
writer.write("Some input data\n");
writer.flush(); // 别忘了刷新输出流
6. 等待进程完成

最后,你可以等待子进程结束,并检查它的退出状态码。

java 复制代码
try {
    int exitCode = process.waitFor();
    System.out.println("Exit Code: " + exitCode);
} catch (InterruptedException e) {
    e.printStackTrace();
}
7.完整案例
java 复制代码
	@PostMapping("/process")
    public String process(@RequestBody String param) throws Exception {
        // 获取python文件所在目录地址
        ProcessBuilder pb = new ProcessBuilder("python", "D:\\DevelopWork\\my-space\\java\\pep7chiao-demos\\exe-py-script\\src\\main\\resources\\script\\spider.py", param);
        // 解决中文乱码
        pb.environment().put("PYTHONIOENCODING", "utf-8");
        // 获取进程的输出流和错误流
        pb.redirectErrorStream(true);
        Process process = pb.start();

        // 读取Python脚本的输出
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String result = "";
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
            result += line;
        }

        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        String errorResult;
        while ((errorResult = errorReader.readLine()) != null) {
            System.out.println(errorResult);
        }

        // 等待进程结束并检查退出状态
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("python脚本执行失败:" + exitCode);
        }

        return result;
    }

三.注意事项

  • 字符编码:确保正确处理字符编码,特别是当你处理非ASCII字符时(如中文)。

  • 异常处理:对可能发生的异常进行适当的处理,以避免程序崩溃。

  • 资源管理 :记得关闭所有打开的流(如 BufferedReaderOutputStreamWriter),以防止资源泄漏。

通过这些步骤,你应该能够轻松地在你的Java应用中使用 ProcessBuilder 来执行外部命令或脚本,并与之交互。

相关推荐
程序员JerrySUN7 分钟前
[特殊字符] 深入理解 Linux 内核进程管理:架构、核心函数与调度机制
java·linux·架构
2302_8097983210 分钟前
【JavaWeb】Docker项目部署
java·运维·后端·青少年编程·docker·容器
蓝婷儿15 分钟前
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
开发语言·python·学习
渣渣盟31 分钟前
基于Scala实现Flink的三种基本时间窗口操作
开发语言·flink·scala
网安INF34 分钟前
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
java·web安全·网络安全·flink·漏洞
一叶知秋哈34 分钟前
Java应用Flink CDC监听MySQL数据变动内容输出到控制台
java·mysql·flink
jackson凌40 分钟前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
chao_78941 分钟前
链表题解——两两交换链表中的节点【LeetCode】
数据结构·python·leetcode·链表
sclibingqing1 小时前
SpringBoot项目接口集中测试方法及实现
java·spring boot·后端
程序员JerrySUN1 小时前
全面理解 Linux 内核性能问题:分类、实战与调优策略
java·linux·运维·服务器·单片机