Processus Java avec flux d'entrée/sortie
Considérez l'extrait de code suivant :
Scanner scan = new Scanner(System.in); Process process = Runtime.getRuntime().exec("/bin/bash"); OutputStream stdin = process.getOutputStream(); InputStream stderr = process.getErrorStream(); InputStream stdout = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin)); String input = scan.nextLine(); input += "\n"; writer.write(input); writer.flush(); input = scan.nextLine(); input += "\n"; writer.write(input); writer.flush(); while ((line = reader.readLine()) != null) { System.out.println("Stdout: " + line); } input = scan.nextLine(); input += "\n"; writer.write(input); writer.close(); while ((line = reader.readLine()) != null) { System.out.println("Stdout: " + line); }
Ce code vous permet pour entrer une commande dans le shell bash et recevoir sa sortie. Cependant, après l'entrée et la sortie initiales, les entrées suivantes n'aboutissent pas au résultat attendu.
Pourquoi cela se produit
Le problème se pose car le code ne gère pas correctement la condition de fin de fichier (EOF) pour la sortie standard du processus bash. La boucle while ((line = reader.readLine()) != null) ne se terminera qu'à la fin du processus, ce qui signifie que s'il n'y a plus de sortie du processus, la boucle se bloquera indéfiniment.
Solution proposée - ProcessBuilder et --EOF-- Handling
Pour résoudre ce problème, considérez ce qui suit modifications :
ProcessBuilder builder = new ProcessBuilder("/bin/bash"); builder.redirectErrorStream(true); Process process = builder.start();
En utilisant ProcessBuilder au lieu de Runtime.getRuntime().exec(), vous pouvez rediriger l'erreur standard du processus bash vers sa sortie standard, garantissant que vous n'avez besoin que d'un seul flux d'entrée.
De plus, le code peut être modifié pour envoyer un délimiteur spécial, --EOF--, pour signaler la fin de la sortie d'une commande. Cela permet au code de séparer de manière fiable la sortie de plusieurs commandes.
while (scan.hasNext()) { String input = scan.nextLine(); if (input.trim().equals("exit")) { // Putting 'exit' amongst the echo --EOF--s below doesn't work. writer.write("exit\n"); } else { writer.write("((" + input + ") & echo --EOF-- || echo --EOF--)\n"); } writer.flush(); line = reader.readLine(); while (line != null && !line.trim().equals("--EOF--")) { System.out.println("Stdout: " + line); line = reader.readLine(); } }
Avec ces modifications, le code gérera de manière fiable plusieurs commandes et leur sortie, fournissant la fonctionnalité souhaitée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!