【问题标题】:Java ProcessBuilder not able to run Python script in JavaJava ProcessBuilder 无法在 Java 中运行 Python 脚本
【发布时间】:2014-10-03 01:00:25
【问题描述】:

null 来自bfr.readLine()

但是,如果我通过触发直接在终端上运行 python 文件是没有问题的:

python C:/Machine_Learning/Text_Analysis/Ontology_based.py

我的 Python 脚本的最后一行是 >> print(data)

下面代码的结果是:

运行 Python 开始:

第一行:空

拾取_JAVA_OPTIONS:-Xmx512M


package text_clustering;

import java.io.*;

public class Similarity {

    /**
     * 
     * @param args
     * 
     */
    public static void main(String[] args){
        try{
            String pythonPath = "C:/Machine_Learning/Text_Analysis/Ontology_based.py";
            //String pythonExe = "C:/Users/AppData/Local/Continuum/Anaconda/python.exe";
            ProcessBuilder pb = new ProcessBuilder("python", pythonPath);
            Process p = pb.start();
            
            BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = "";
            System.out.println("Running Python starts: " + line);
            line = bfr.readLine();
            System.out.println("First Line: " + line);
            while ((line = bfr.readLine()) != null){
                System.out.println("Python Output: " + line);
                
                
            }

        }catch(Exception e){System.out.println(e);}
    }

}

【问题讨论】:

  • 您最好也抓住错误流并检查它输出的内容,因为您可能会遇到错误情况。或者,您可以将错误流与输入流结合起来,然后读取。
  • @HovercraftFullOfEels,谢谢!抱歉,我是 Java 和 Python 的新手......所以你的意思是在 Java 代码块中,而不是捕获异常,我抛出异常?再次感谢!
  • 没有。将您的 catch 块更改为 e.printStackTrace() 以获取更多信息,但这是一个单独的问题。我的意思是您应该像捕获 InputStream 一样捕获 ErrorStream。但最简单的方法是调用pb.redirectErrorStream(true); 将错误流重定向到输入流。
  • hmmm,我在 try{} 块中添加了 pb.redirectErrorStream(true) 并在 catch{} 块中添加了 e.printStackTrace() ......但似乎没有机会?我错过了什么吗?你介意举个例子吗?非常感谢
  • 我的建议只是查看是否发生了您没有看到的错误。只要您在创建 ProcessBuilder 对象后立即重定向错误流,就可以遵循我的建议。那么可能还有其他问题。如果你不使用 Java,你如何运行你的 python 脚本?是否需要给出 python.exe 的完整路径?

标签: java python processbuilder


【解决方案1】:

通常在使用ProcessBuilder 执行命令时,不会考虑PATH 变量。您的 python C:/Machine_Learning/Text_Analysis/Ontology_based.py 直接在您的 CMD shell 中运行,因为它可以使用 PATH 变量定位 python 可执行文件。请在您的 Java 代码中提供 python 命令的绝对路径。在下面的代码中,将<Absolute Path to Python> 替换为python 命令及其库的路径。通常它会在 Windows 中默认类似于 C:\Python27\python

package text_clustering;

import java.io.*;

public class Similarity {

    /**
     * 
     * @param args
     * 
     */
    public static void main(String[] args){
        try{
            String pythonPath = "C:/Machine_Learning/Text_Analysis/Ontology_based.py";
            //String pythonExe = "C:/Users/AppData/Local/Continuum/Anaconda/python.exe";
            ProcessBuilder pb = new ProcessBuilder(Arrays.asList("<Absolute Path to Python>/python", pythonPath));
            Process p = pb.start();

            BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = "";
            System.out.println("Running Python starts: " + line);
            int exitCode = p.waitFor();
            System.out.println("Exit Code : "+exitCode);
            line = bfr.readLine();
            System.out.println("First Line: " + line);
            while ((line = bfr.readLine()) != null){
                System.out.println("Python Output: " + line);


            }

        }catch(Exception e){System.out.println(e);}
    }

}

【讨论】:

    【解决方案2】:

    当脚本被杀死/终止时,从标准输入读取返回 null。执行 Process#waitFor 并查看 exitValue 是什么。如果它不是 0,那么您的脚本很可能正在死亡。

    我会尝试让它与只写入值的愚蠢脚本一起工作。确保从 python 打印所有错误信息。

    【讨论】:

      【解决方案3】:
      try {
      
          Process p = Runtime.getRuntime().exec(
                  "python   D://input.py   ");
          BufferedReader in = new BufferedReader(new InputStreamReader(
                  p.getInputStream()));
      
          String line;  
              while ((line = in.readLine()) != null) {  
                  System.out.println(line);  
              }  
              in.close();
              p.waitFor();
      
      
      
      } catch (Exception e) {
      }
      

      【讨论】:

        【解决方案4】:
        try {
            ProcessBuilder pb = new ProcessBuilder("C:/Python27/python", "D://searchTestJava//input.py");
            Process p = pb.start();
            BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
        
            System.out.println(".........start   process.........");
            String line = "";
            while ((line = bfr.readLine()) != null) {
                System.out.println("Python Output: " + line);
            }
        
            System.out.println("........end   process.......");
        
        } catch (Exception e) {
            System.out.println(e);
        }
        

        【讨论】:

        • 稍微解释一下你的代码做什么也不错。
        • 这有帮助。谢谢。
        【解决方案5】:

        我试过this 一个。该脚本运行一个带有 Java 参数的 python 文件。它还记录您的程序正在执行哪一行。希望这会有所帮助。

            import java.io.BufferedReader;
            import java.io.IOException;
            import java.io.InputStreamReader;
            import java.io.Reader;
        
            public class Test {
              public static void main(String... args) throws IOException {
        
                ProcessBuilder pb =
                        new ProcessBuilder("python","samples/test/table_cv.py","1.pdf");
        
                pb.redirectErrorStream(true);
                Process proc = pb.start();
        
                Reader reader = new InputStreamReader(proc.getInputStream());
                BufferedReader bf = new BufferedReader(reader);
                String s;
                while ((s = bf.readLine()) != null) {
                    System.out.println(s);
                }
            }
          }
        

        【讨论】:

          最近更新 更多