实现在Java中执行python代码或py脚本(可传参数)

写在前面

  最近用Java写服务端程序时,遇到这样一个需求:需要把用python写的机器学习算法部署到服务器上,然后Java执行py脚本,并且取得算法执行的结果。在网上找了很久,有些跑不通,有些是基于windows的,我的服务器是linux的,遇到了不少坑= =好不容易解决了,记录一下。

注:Web服务器:Tomcat 服务器OS:CentOS 7 开发工具:Eclipse

直接嵌入python代码(使用PythonInterpreter)

  • 适用情形:要嵌入的python代码不长
  • 步骤:
    • 下载Jython,导入jython.jar到项目lib中
    • 引用org.python包
    • 测试代码如下:
import javax.script.*;    
import org.python.util.PythonInterpreter;  
import java.io.*;  
import static java.lang.System.*;  
public class Test  
{  
 public static void main(String args[])  
 {      
  PythonInterpreter interpreter = new PythonInterpreter();  
  interpreter.exec("print "TEST";");  
 }
}

执行python脚本(使用PythonInterpreter)

  • 适用情形: python代码为py文件形式
  • 步骤:
    • 下载Jython,导入jython.jar到项目lib中
    • 引用org.python包
    • 测试代码如下:
import javax.script.*;    
import org.python.util.PythonInterpreter;  
import java.io.*;  
import static java.lang.System.*;  
public class Test  
{  
 public static void main(String args[])  
 {      
  PythonInterpreter interpreter = new PythonInterpreter();  
  InputStream filepy = new FileInputStream("D:\\demo.py");   
  interpreter.execfile(filepy);   
  filepy.close();  
 }//main  
}

执行python脚本(使用Runtime.getRuntime())

  • 适用情形:
    • python脚本中import了外来模块
    • 需要传入数据给python脚本
    • PS:上面两种不知道为啥老是会报错= =所以最后我用的是这种……
  • 测试代码:
// 定义传入参数
int age;
// 接收python脚本的输出结果
int result;
// 若Python脚本在windows主机中
String cmdStr_windows = "python D:\\demo.py"+ " " + age;
// 若Python脚本在Linux主机中
String cmdStr_linux = "python /home/pythonCode/demo.py"+ " " + age);
// 定义缓冲区、正常结果输出流、错误信息输出流
byte[] buffer = new byte[1024];  
ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
ByteArrayOutputStream outerrStream = new ByteArrayOutputStream();   

try {
    proc = Runtime.getRuntime().exec(cmdStr_linux);
    InputStream errStream = proc.getErrorStream();
    InputStream stream = proc.getInputStream();

    // 流读取与写入
    int len = -1;  
    while ((len = errStream.read(buffer)) != -1) {  
        outerrStream.write(buffer, 0, len);  
    }  
    while ((len = stream.read(buffer)) != -1) {  
        outStream.write(buffer, 0, len);  
    }  
    proc.waitFor();// 等待命令执行完成

    // 打印流信息
    System.out.println(outStream.toString());
    System.out.println(outerrStream.toString());

    // 将接收的输出结果转换为目标类型
    res = Integer.parseInt(outStream.toString());
} catch (Exception e) {
    e.printStackTrace();
}
  • demo.py脚本如下:
import sys
age = sys.argv[1]
res = 1111
print res
  • 注:
    • 若python脚本在Linux主机中,注意文件路径要为绝对路径,而且不能用~代替家目录!!!必须写成/XX/XXX的形式
    • 若要传递多个参数,需要以空格间隔
    • 接收python脚本执行结果可用java的InputStream截获控制台输出
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值