Перенаправление stdin и stdout на Java



Я пытаюсь перенаправить stdin и stdout подпроцесса в java, в конечном итоге я собираюсь получить вывод в JTextArea или что-то в этом роде.



Вот мой текущий код,



Process cmd = Runtime.getRuntime().exec("cmd.exe");

cmd.getOutputStream().write("echo Hello World".getBytes());
cmd.getOutputStream().flush();

byte[] buffer = new byte[1024];
cmd.getInputStream().read(buffer);
String s = new String(buffer);

System.out.println(s);


Вывод выглядит следующим образом:



Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:(Current Directory)>


Я ожидаю увидеть вывод строки "Hello World".
Может быть, потому, что родительский процесс не живет достаточно долго?



Я также хотел бы иметь возможность отправлять и получать несколько команд.

788   2  

2 ответов:

Вы попытались записать в выходной поток, прежде чем пытаться слушать входной поток, поэтому имеет смысл, что вы ничего не видите. Для этого вам нужно будет использовать отдельные потоки для ваших двух потоков.

То есть,

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Scanner;

public class Foo {
   public static void main(String[] args) throws IOException {
      Process cmd = Runtime.getRuntime().exec("cmd.exe");

      final InputStream inStream = cmd.getInputStream();
      new Thread(new Runnable() {
         public void run() {
            InputStreamReader reader = new InputStreamReader(inStream);
            Scanner scan = new Scanner(reader);
            while (scan.hasNextLine()) {
               System.out.println(scan.nextLine());
            }
         }
      }).start();

      OutputStream outStream = cmd.getOutputStream();
      PrintWriter pWriter = new PrintWriter(outStream);
      pWriter.println("echo Hello World");
      pWriter.flush();
      pWriter.close();
   }
}

И вы действительно не должны игнорировать поток ошибок, но вместо этого должны проглотить его, так как игнорирование его иногда поджарит ваш процесс, поскольку он может исчерпать буферное пространство.

В настоящее время Runtime.getRuntime().exec() является устаревшим (для всех практических целей). Лучше использовать классProcessBuilder ; в частности, его метод start() вернет объектProcess с методами доступа к потокам stdin и stdout, которые могут быть перенаправлены туда, где они вам нужны. Взгляните на этот пост для получения более подробной информации.

Comments

    Ничего не найдено.