Comprendre les problèmes de lecture de la sortie de commande JSch
Dans le code Java fourni utilisant JSch, vous rencontrez une situation dans laquelle le programme se bloque en essayant de lire à partir d’un flux de lecteur utilisé pour capturer le résultat de la commande. Cet article explique la cause de ce problème et propose une solution.
Analyse du problème
Le problème fondamental vient du fait de ne pas consommer en permanence la sortie produite par la commande exécutée. Les commandes JSch accumulent la sortie dans un tampon interne, et si le tampon se remplit avant d'être consommé, cela peut provoquer un blocage, où la commande se bloque en attendant que le tampon soit effacé.
Solution
Pour résoudre ce problème, vous devez lire en permanence à la fois la sortie standard et les flux d'erreurs standard de la commande, même en attendant la fin de la commande. Cela garantit que le tampon de sortie ne se remplit jamais et que la commande ne se bloque pas.
Exemple de code
Voici une version étendue de votre code qui intègre cette solution :
<code class="java">ChannelExec channel = (ChannelExec)session.openChannel("exec"); channel.setCommand(...); // Set the command to execute ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream(); InputStream in = channel.getInputStream(); InputStream err = channel.getExtInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; outputBuffer.write(tmp, 0, i); } while (err.available() > 0) { int i = err.read(tmp, 0, 1024); if (i < 0) break; errorBuffer.write(tmp, 0, i); } if (channel.isClosed()) { if ((in.available() > 0) || (err.available() > 0)) continue; System.out.println("exit-status: " + channel.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } System.out.println("output: " + outputBuffer.toString("UTF-8")); System.out.println("error: " + errorBuffer.toString("UTF-8")); channel.disconnect();</code>
Dans cet exemple, les boucles while lisent en continu les flux de sortie (in et err) tout en surveillant l'état de la commande (channel.isClosed()). Cela garantit que toutes les sorties sont capturées, même si la commande produit une grande quantité de données.
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!