spring boot读取resources目录下的python脚本执行

spring boot读取resources目录下的python脚本执行,第1张

最近项目有点忙,有段时间没有更新了,今天趁放假在家,水一篇文章。



一、问题描述

如何在spring boot工程中,通过java代码调用执行存放在resources目录下的python脚本?



二、分析

1、要执行python脚本,服务器上一定要配置对应的python执行环境。



2、spring boot工程中resources目录下的python文件只能通过流读取出来,然后保存为临时文件,才能调用python脚本执行命令。




三、代码实战

test.py的内容:

#!/usr/bin/python3

import sys

print ('参数个数为:', len(sys.argv), '个参数。


') print ('参数列表:', str(sys.argv)) print ('脚本名:', str(sys.argv[0])) print("Hello, World!")

/**
 * @Description python执行工具类
 */
@Slf4j
public class PythonUtil {
    /**
     * 执行脚本
     */
    public  static void exec(String path, List<String> params) throws Exception {
        //InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
        InputStream inputStream = PythonUtil.class.getClassLoader().getResourceAsStream(path);
        File somethingFile = File.createTempFile("test", ".py");
        String filePath = null;
        String commond = null;
        try {
            FileUtils.copyInputStreamToFile(inputStream, somethingFile);
            filePath = somethingFile.getAbsolutePath();
            log.info("文件路径:{}",filePath);

            Runtime runTime = Runtime.getRuntime();
            commond = "python3 " + filePath;
            if(params!=null && params.size()>0){
                commond += " " + params.stream().collect(Collectors.joining(" "));
            }
            log.info("执行脚本[{}]",commond);

            Process proc =  runTime.exec(commond);
            BufferedReader bfr = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = "";
            while ((line = bfr.readLine()) != null) {
                log.info(line);
            }
            proc.waitFor();

        } catch (Exception e) {
            log.error("脚本[{}]执行失败",commond);
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(inputStream);
            //删除临时文件
            somethingFile.deleteOnExit();
        }
    }

    /**
     * 无参方法
     */
    public  static void exec(String path) throws Exception {
        exec(path,null);
    }

    public static void main(String[] args) throws Exception {
        List<String> params = new ArrayList<>();
        params.add("参数1");
        params.add("参数2");
        params.add("参数3");
        PythonUtil.exec("test.py",params);
    }
}

执行结果:


四、其他方式

Jython在执行普通py脚本时速度很慢,而且在含有第三方库(requests, jieba…)时bug很多,不易处理。


原因在于,python执行时的sys.path和Jython的sys.path路径不一致,以及Jython的处理不是很好。


<!--Maven依赖,jar包自行前往仓库下载-->
<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.7.0</version>
</dependency>

1. 直接执行Python脚本代码

1 PythonInterpreter interpreter = new PythonInterpreter();  
2 interpreter.exec("days=('mod','Tue','Wed','Thu','Fri','Sat','Sun'); ");  

2. 执行python .py文件

 PythonInterpreter interpreter = new PythonInterpreter();  
 InputStream filepy = new FileInputStream("D:\demo.py"); 
 interpreter.execfile(filepy);  ///执行python py文件
 filepy.close();

3. 使用Runtime.getRuntime()执行脚本文件
这种方式和.net下面调用cmd执行命令的方式类似。


如果执行的python脚本有引用第三方包的,建议使用此种方式。


使用上面两种方式会报错java ImportError: No module named arcpy。


Process proc = Runtime.getRuntime().exec("python  D:\demo.py");  
proc.waitFor();  

其中,方式一和方式二都依赖Jython,对有第三方依赖的脚本执行不友好,且实现效率较慢,所以更推荐方案三用cmd执行命令的方式。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/571625.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存