Java应用与Python应用的交互

3 投票
6 回答
6824 浏览
提问于 2025-04-15 17:30

我有一个Python应用程序,我无法编辑,从我的角度来看它就像一个黑箱。这个Python应用程序知道怎么处理文本,并返回处理后的文本。

我还有一个用Java写的应用程序,它知道怎么收集未处理的文本。

目前的状态是,Python应用程序每隔一段时间就会批量处理一次。

我想让Python应用程序成为这个流程的一部分:Java应用程序收集文本,然后请求Python应用程序处理这些文本,并返回处理后的结果。

你觉得最简单的解决方案是什么呢?

谢谢,
Rod

6 个回答

6

使用 ProcessBuilder 来执行你的 Python 代码,作为一个过滤器:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class PBTest {

    public static void main(String[] args) {
        ProcessBuilder pb = new ProcessBuilder(
            "python3", "-c", "print(42)");
        pb.redirectErrorStream(true);
        try {
            Process p = pb.start();
            String s;
            BufferedReader stdout = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
            while ((s = stdout.readLine()) != null) {
                System.out.println(s);
            }
            System.out.println("Exit value: " + p.waitFor());
            p.getInputStream().close();
            p.getOutputStream().close();
            p.getErrorStream().close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
6

你可以看看 Jython - 它让你可以直接在Java代码中运行Python程序,而且可以很方便地在两者之间进行互动。

7

我对Jython之类的东西一点都不了解。我觉得如果你能在Java应用程序需要转换文本时,不用每次都启动一个新进程来执行两个程序,那这可能是最好的解决方案。不过,简单的概念验证就是从Java应用程序中执行一个单独的进程来让它工作。接下来,你可以用各种工具来增强这个执行过程。

从Java执行一个单独的进程

String[] envprops = new String[] {"PROP1=VAL1", "PROP2=VAL2" };
Process pythonProc = Runtime.getRuntime().exec(
   "the command to execute the python app", 
    envprops, 
    new File("/workingdirectory"));

// get an outputstream to write into the standard input of python
OutputStream toPython = pythonProc.getOutputStream();

// get an inputstream to read from the standard output of python
InputStream fromPython = pythonProc.getInputStream();

// send something
toPython.write(.....);
// receive something
fromPython.read(....);

重要提示:字符和字节是不同的

很多人对此认识不足。

在字符和字节之间转换时要小心(记住,Writer和Reader是处理字符的,Input和Output流是处理字节的,转换时需要编码,你可以使用OutputStreamWriter将字符串转换为字节并发送,使用InputStreamReader将字节转换为字符并读取)。

撰写回答