Проблема при вызове кода Python из Java (без использования jython) - PullRequest
0 голосов
/ 25 января 2019

Я нашел это как один из способов запуска (используя метод exec ()) скрипта Python из Java.У меня есть один простой оператор печати в файле 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");

В чем проблема?

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Один из способов запустить процесс 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();
    }
}
0 голосов
/ 25 января 2019

Вы можете использовать API-интерфейс ProcessBuilder, перенаправив вывод в файл, а затем дождаться результата.

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:

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

Чтобы увидеть вывод оператора print, вам нужно подождать и перенаправить потоки. То же самое для потока ошибок.

Теперь, если вы сломаете скрипт на python, как это:

print("Hello from python')

Вы также должны увидеть распечатанную ошибку.

0 голосов
/ 25 января 2019

Я думаю, вы можете попытать счастья с классом ProcessBuilder.

Если я правильно прочитал документацию по Oracle, входы и выходы std по умолчанию направляются в каналы , но ProcessBuilder предлагает простой способ явно установить вывод (или ввод) в файл в вашей системе или что-то еще .

Если вы хотите, чтобы ваша программа на 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();
...