Java程序中执行Python脚本

https://tool.lu/en_US/article/1us/preview

有一个Python脚本

import time
if __name__ == '__main__':
    for i in range(100):
        time.sleep(1)
        print(i)

需要在Java程序中调用,并希望拿到执行的日志

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 *  * @Author : wangbin
 *   * @Date : 2022/6/17 16:20
 *    * @Description:
 *     */
public class ShellTask {


    public static void main(String [] args){
        Runtime runtime = Runtime.getRuntime();

        String[] command={"/usr/bin/python3 ","/opt/module/my_test.py"};
        System.out.println(Arrays.toString(command));
        try {
            Process exec = runtime.exec("/usr/bin/python3 /opt/module/my_test.py");
            InputStream inputStream = exec.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line=null;
            while((line=reader.readLine())!=null){
                System.out.println(line);
            }
       inputStream.close();
            int i = exec.waitFor();
            System.out.println(i);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

}

有一个缺点,就是只有Python任务执行完之后才能拿到日志

那么如果我们要执行一个时间稍微长一点的任务,等任务执行完才能拿到日志,肯定是不合适的。

想要拿到实时日志,我本来以为要修改Java代码,其实是要修改Python脚本

只需要在原来的Python脚本上,修改一行代码,即可实现日志实时刷新

import time
if __name__ == '__main__':
    for i in range(10):
        time.sleep(1)
        print(i, flush=True)

 一般情形,上面的问题已经解决了,但如果是做平台的,肯定不会满意上面的解决方法。

平台是给用户用的,用户的脚本写什么平台无法控制。

因此上面在python脚本中修改代码的方式,不具有通用性。

经查,python 支持-u参数,意思是不缓存标准输出和标准错误。因此可以达到相同的效果

 @Test
    public void test2(){
        Runtime runtime = Runtime.getRuntime();

       String command="C:\\Users\\G007112\\AppData\\Local\\Programs\\Python\\Python38\\python.exe -u C:\\Users\\G007112\\Desktop\\my_test2.py";
        System.out.println(command);
        try {
            Process exec = runtime.exec(command);
            InputStream inputStream = exec.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line=null;
            while((line=reader.readLine())!=null){
                System.out.println(line);
            }
            inputStream.close();
            int i = exec.waitFor();
            System.out.println(i);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

 

posted @ 2022-06-17 17:04  Mars.wang  阅读(919)  评论(0编辑  收藏  举报