简体   繁体   English

从Java调用Python代码的问题(不使用jython)

[英]Issue in calling Python code from Java (without using jython)

I found this as one of the ways to run (using exec() method) python script from java. 我发现这是从java运行(使用exec()方法)python脚本的方法之一。 I have one simple print statement in python file. 我在python文件中有一个简单的print语句。 However, my program is doing nothing when I run it. 但是,当我运行它时,我的程序无效。 It neither prints the statement written in python file nor throws an exception. 它既不打印用python文件编写的语句也不抛出异常。 The program just terminates doing nothing: 该程序只是终止无所作为:

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

Even this is not creating the output file: 即使这不是创建输出文件:

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

What is the issue? 有什么问题?

I think you could try your luck with the ProcessBuilder class. 我想你可以尝试使用ProcessBuilder类。

If I read the Oracle documentation correctly, the std inputs and outputs are directed to pipes by default but the ProcessBuilder has an easy method for you to explicitly set output (or input) to a file on your system or something else . 如果我正确读取Oracle文档,默认情况下std输入和输出将定向到管道, ProcessBuilder有一个简单的方法可以显式地将输出(或输入)设置到系统上的文件或其他内容

If you want your Python program to use the same output as your Java program (likely stdout and stderr), you can use stg like this: 如果你希望你的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();

You can use the ProcessBuilder API, redirecting the output to a file and then wait for the result. 您可以使用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);
        }

    }
}

The python file test.py contains a simple print statement: python文件test.py包含一个简单的print语句:

print("Hello from python")

I guess it would be even simpler, if you do not need to wait for the result. 如果您不需要等待结果,我想它会更简单。

Using the Process API should work, too. 使用Process API也应该有效。

Like in your example (I am using the same constants declared above): 就像在你的例子中(我使用上面声明的相同常量):

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));

To see the output of the print statement, you need to wait and redirect the streams. 要查看print语句的输出,您需要等待并重定向流。 Same for the error stream. 错误流相同。

Now if you break the python script like this: 现在如果你像这样打破python脚本:

print("Hello from python')

you should be able to see the error printed as well. 你应该能够看到打印的错误。

One way to start a python process is using an entrypoint - test.cmd 启动python进程的一种方法是使用入口点 - test.cmd

echo Hello
python hello.py

here is hello.py 这是hello.py

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

Here is my Java code: 这是我的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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM