Ни один из вариантов, в которых вы пытаетесь выполнить "python3 "+script
и эквиваленты, не будет работать. script
- это InputStream
, а не путь в файловой системе, поэтому простое объединение его с String
не даст вам ничего значимого. Кроме того, поскольку ваш скрипт находится не в собственном файле, и интерпретатор python не может извлечь его просто, просто вызвать его в таком виде не получится.
Однако что вы можете сделать, это выполнить
python3 -
Опция -
здесь (по крайней мере, в BSD-подобных системах) означает «читать со стандартного ввода и интерпретировать его как сценарий». Затем на стороне Java вы можете прочитать ресурс, упакованный в jar, как поток и направить его на стандартный ввод процесса python.
Подробнее о выборе правильного пути для ресурса см. Как определить правильный путь для файлов F XML, CSS файлов, изображений и других ресурсов, необходимых моему приложению JavaFX? .
Следующее, в котором скрипт просто помещается в тот же пакет, что и класс, у меня работает:
PythonRunner. java:
package example.python;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class PythonRunner {
public static void main(String[] args) throws Exception {
String pythonInterpreter = "/usr/bin/python3" ; // default
if (args.length > 0) {
pythonInterpreter = args[0] ;
}
InputStream script = PythonRunner.class.getResourceAsStream("script.py");
Process pythonProcess = new ProcessBuilder(pythonInterpreter, "-")
.start();
// This thread reads the output from the process and
// processes it (in this case just dumps it to standard out)
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(pythonProcess.getInputStream()))) {
for (String line ; (line = reader.readLine()) != null ;) {
System.out.println(line);
}
} catch (IOException exc) {
exc.printStackTrace();
}
}).start();
// read the script from the resource, and pipe it to the
// python process's standard input (which will be read because
// of the '-' option)
OutputStream stdin = pythonProcess.getOutputStream();
byte[] buffer = new byte[1024];
for (int read = 0 ; read >= 0 ; read = script.read(buffer)) {
stdin.write(buffer, 0, read);
}
stdin.close();
}
}
script.py:
import sys
for i in range(10):
print("Spam")
sys.exit(0)
MANIFEST .MF
Manifest-Version: 1.0
Main-Class: example.python.PythonRunner
Макет Eclipse:
Содержимое Jar-файла и результат выполнения:
$ jar tf runPython.jar
META-INF/MANIFEST.MF
example/python/PythonRunner.class
example/python/script.py
$ java -jar runPython.jar
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
Spam
$