【问题标题】:Issue in calling Python code from Java (without using jython)从 Java 调用 Python 代码的问题(不使用 jython)
【发布时间】:2019-01-25 05:00:25
【问题描述】:

我发现这是从 java 运行(使用 exec() 方法)python 脚本的一种方法。我在 python 文件中有一个简单的打印语句。但是,当我运行它时,我的程序什么也没做。它既不打印写在 python 文件中的语句也不抛出异常。该程序只是终止什么都不做:

Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py");

即使这样也不会创建输出文件:

Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py output.txt 2>&1");

有什么问题?

【问题讨论】:

  • 如果您使用 Windows 命令 shell 程序 cmd.exe 手动键入确切的字符串,它会达到您的预期吗?
  • 是的,这两个语句都给出了预期的结果。

标签: java python python-3.x jython


【解决方案1】:

我认为您可以使用 ProcessBuilder 类来试试运气。

如果我正确阅读了 Oracle 文档,默认情况下标准输入和输出将定向到管道但是 ProcessBuilder 有一个简单的方法让您明确地set output (or input) to a file on your system or something else

如果您希望您的 Python 程序使用与您的 Java 程序相同的输出(可能是 stdout 和 stderr),您可以像这样使用 stg:

ProcessBuilder pb = new ProcessBuilder("C:\\Python\\Python36-32\\python.exe", "C:\\test2.py");
pb.redirectOutput(Redirect.INHERIT);
Process p = pb.start();

【讨论】:

  • 收到此错误:java.io.IOException: Cannot run program "C:\Python\Python36-32\python.exe C:\test2.py": CreateProcess error=2, The system cannot find the file specified at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) at RunninPythonFromJava.main(RunninPythonFromJava.java:16) Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
  • 这个怎么样:stackoverflow.com/a/40648879/9070798?这能解决你的问题吗?
  • 这就像一个魅力 - ProcessBuilder pb = new ProcessBuilder("C:\\Python\\Python36-32\\python.exe", "C:\\test2.py");。更进一步,如何将参数传递给 python 并获取返回数据?
  • 您可以像在终端上一样传递参数,方法是将它们添加到代码中的命令行中:... new ProcessBuilder("C:\Python\\Python36-32\\python.exe", "C:\\test2.py", "arg0", "arg1"); 或者您是否希望在 Java 程序和 Python 之间进行某种交互程序 ?在这种情况下,您可以让您的 Java 程序将一些内容写入 python 进程的输入流。至于返回数据我不知道你在做什么。您可以做的一件事是让 Java 读取您的 python 程序在 stdout 上输出的内容,但这对我来说似乎很烦人。
【解决方案2】:

您可以使用 ProcessBuilder API,将输出重定向到文件,然后等待结果。

public class Main {

    public static final String PYTHON_PATH = "D:\\Anaconda3\\python.exe";
    public static final String PATH_TO_SCRIPT = "D:\\projects\\StartScript\\test.py";

    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(PYTHON_PATH, PATH_TO_SCRIPT);

        // Redirect output to a file
        builder.redirectOutput(new File("output.txt"));

        builder.start().waitFor();

        // Print output to console
        ProcessBuilder.Redirect output = builder.redirectOutput();
        File outputFile = output.file();
        BufferedReader br = new BufferedReader(new FileReader(outputFile));

        String st;
        while ((st = br.readLine()) != null) {
            System.out.println(st);
        }

    }
}

python 文件 test.py 包含一个简单的打印语句:

print("Hello from python")

如果您不需要等待结果,我想它会更简单。

使用 Process API 也应该可以。

就像你的例子一样(我使用上面声明的相同常量):

Process p = Runtime.getRuntime().exec(PYTHON_PATH + " " + PATH_TO_SCRIPT);
p.waitFor();

byte[] buffer = new byte[1024];
byte[] errBuffer = new byte[1024];

p.getInputStream().read(buffer);
p.getErrorStream().read(errBuffer);

System.out.println(new String(buffer));
System.out.println(new String(errBuffer));

要查看打印语句的输出,您需要等待并重定向流。错误流也一样。

现在如果你像这样破坏 python 脚本:

print("Hello from python')

您也应该能够看到打印的错误。

【讨论】:

    【解决方案3】:

    启动 python 进程的一种方法是使用入口点 - test.cmd

    echo Hello
    python hello.py
    

    这里是 hello.py

    #!/usr/bin/env python3
    import os
    if not os.path.exists('dir'):
        os.makedirs('dir')
    

    这是我的 Java 代码:

    public static void main(String[] args) throws IOException {
        try {
            Process p = Runtime.getRuntime().exec("test.cmd");
            p.waitFor();
            Scanner sc = new Scanner(p.getInputStream());
            while(sc.hasNextLine()){
                System.out.println(sc.nextLine());
            }
            sc.close();
        } catch (Exception err) {
            err.printStackTrace();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多