Maison > Java > javaDidacticiel > le corps du texte

Pourquoi ma commande JSch se bloque-t-elle lors de la lecture du résultat ?

DDD
Libérer: 2024-10-31 00:33:30
original
729 Les gens l'ont consulté

Why is my JSch command hanging while reading output?

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!