J'ai trouvé cela comme l'un des moyens d'exécuter (en utilisant la méthode exec ()) un script python à partir de java. J'ai une simple déclaration d'impression dans un fichier python. Cependant, mon programme ne fait rien lorsque je l'exécute. Il n'imprime pas l'instruction écrite dans le fichier python ni ne lève d'exception. Le programme s'arrête juste de ne rien faire:
Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py output.txt 2>&1");
Même cela ne crée pas le fichier de sortie:
Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py");
Quel est le problème? P >
3 Réponses :
Je pense que vous pourriez tenter votre chance avec la classe ProcessBuilder.
Si je lis correctement la documentation Oracle, les entrées et sorties std sont dirigées vers les tubes par défaut mais ProcessBuilder a une méthode simple pour que vous puissiez explicitement définit la sortie (ou l'entrée) sur un fichier sur votre système ou autre .
Si vous voulez que votre programme Python utilise la même sortie que votre programme Java (probablement stdout et stderr), vous pouvez utiliser stg comme ceci:
ProcessBuilder pb = new ProcessBuilder("C:\\Python\\Python36-32\\python.exe", "C:\\test2.py"); pb.redirectOutput(Redirect.INHERIT); Process p = pb.start();
p>
J'obtiens cette erreur: java.io.IOException: Impossible d'exécuter le programme "C: \ Python \ Python36-32 \ python.exe C: \ test2.py": Erreur CreateProcess = 2, le système ne trouve pas le fichier spécifié à java.lang.ProcessBuilder.start (ProcessBuilder.java:1048) à RunninPythonFromJava.main (RunninPythonFromJava.java:16) Causé par: java.io.IOException: erreur CreateProcess = 2, le système ne trouve pas le fichier spécifié code >
Que diriez-vous de ceci: stackoverflow.com/a/40648879/9070798 ? Est-ce que cela résout votre problème?
Cela a fonctionné comme un charme - ProcessBuilder pb = new ProcessBuilder ("C: \\ Python \\ Python36-32 \\ python.exe", "C: \\ test2.py");
. Pour aller plus loin, comment puis-je transmettre les arguments à python et obtenir les données de retour?
Vous pouvez passer des arguments comme sur un terminal, en les ajoutant à votre ligne de commande dans votre code: ... new ProcessBuilder ("C: \ Python \\ Python36-32 \\ python.exe", "C : \\ test2.py "," arg0 "," arg1 ");
Ou voulez-vous avoir une sorte d'interaction entre votre programme Java et votre programme Python? Dans ce cas, vous pouvez faire en sorte que votre programme Java écrive des éléments dans le flux d'entrée de votre processus python. Quant aux données de retour, je ne sais pas ce que vous faites. Une chose que vous pourriez faire est de faire en sorte que Java lise ce que votre programme python produit sur stdout, mais cela me semble assez ennuyeux.
Une façon de démarrer un processus python consiste à utiliser un point d'entrée - test.cmd
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(); } }
voici hello.py
#!/usr/bin/env python3 import os if not os.path.exists('dir'): os.makedirs('dir')
Ici est mon code Java:
echo Hello python hello.py
Vous pouvez utiliser l'API ProcessBuilder, rediriger la sortie vers un fichier puis attendre le résultat.
print("Hello from python')
Le fichier python test.py contient une instruction d'impression simple:
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));
Je suppose que ce serait encore plus simple, si vous n'avez pas besoin d'attendre le résultat.
L'utilisation de l'API Process devrait également fonctionner.
Comme dans votre exemple (j'utilise les mêmes constantes déclarées ci-dessus):
print("Hello from python")
Pour voir la sortie de l'instruction print, vous devez attendre et rediriger les flux . Idem pour le flux d'erreurs.
Maintenant, si vous cassez le script python comme ceci:
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); } } }
vous devriez également pouvoir voir l'erreur imprimée.
Si vous tapez manuellement cette chaîne exacte en utilisant le programme shell de commande Windows
cmd.exe
, fait-il ce que vous attendez?Oui, les deux déclarations donnent les résultats attendus.