我有一个Python应用程序,但是从我的角度来看,它是一个黑盒子,我无法编辑。这个Python应用程序知道如何处理文本并返回已处理的文本。
我还有另一个Java编写的应用程序,它知道如何收集未经处理的文本。
当前状态是,Python应用程序每x分钟以批处理模式运行。
我想将Python处理部分作为流程的一部分:Java应用程序收集文本并请求Python应用程序进行处理,并返回已处理的文本。
你认为最简单的解决方案是什么?
谢谢, Rod
我有一个Python应用程序,但是从我的角度来看,它是一个黑盒子,我无法编辑。这个Python应用程序知道如何处理文本并返回已处理的文本。
我还有另一个Java编写的应用程序,它知道如何收集未经处理的文本。
当前状态是,Python应用程序每x分钟以批处理模式运行。
我想将Python处理部分作为流程的一部分:Java应用程序收集文本并请求Python应用程序进行处理,并返回已处理的文本。
你认为最简单的解决方案是什么?
谢谢, Rod
我对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(....);
重要提示:字符和字节不同
许多人低估了这一点。
在进行字符到字节的转换时要小心(记住Writers/Readers是为字符设计的,Input/OutputStreams是为字节设计的,编码是必要的转换方式,您可以使用OuputStreamWriter
将字符串转换为字节并发送,InputStreamReader
用于将字节转换为字符并读取它们)。
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();
}
}
}
您可以尝试使用Jython - 这个工具可以让您直接在Java代码中运行Python程序,并且可以无缝地来回交互。
将其中一个作为某种服务公开,可能是Web服务。另一个选项是将Python代码移植到Jython。
一个可能的解决方案是使用jpype。这允许您从Python启动JVM并在它们之间传递数据。
另一个解决方案可能是将Python程序编写为过滤器(从stdin读取数据并将结果写入stdout),然后作为管道运行。但是我不知道Java对此的支持情况-根据Sun文档,他们的管道概念仅支持同一JVM上线程之间的通信。