Maison > Java > javaDidacticiel > Comment gérer correctement les flux d'entrée/sortie dans les processus Java pour éviter le blocage ?

Comment gérer correctement les flux d'entrée/sortie dans les processus Java pour éviter le blocage ?

Mary-Kate Olsen
Libérer: 2024-12-17 18:00:16
original
661 Les gens l'ont consulté

How to Properly Handle Input/Output Streams in Java Processes to Avoid Blocking?

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

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

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();
    }
}
Copier après la connexion

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!

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal