Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect stdin and stdout in Java

I'm trying to redirect stdin and stdout of a subprocess in java, eventually i'm going to have the output go to a JTextArea or something.

Here is my current code,

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);

The output looks like this:

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

C:\(Current Directory)>

I'm expecting to see the "Hello World" string outputted. Maybe because the parent process isn't staying alive long enough?

I'd also like to be able to send and receive multiple commands.

like image 920
Josh Avatar asked May 02 '12 03:05

Josh


2 Answers

Nowadays Runtime.getRuntime().exec() is deprecated (for all practical purposes). Better use the ProcessBuilder class; in particular, its start() method will return a Process object with methods for accessing the stdin and stdout streams, which can be redirected wherever you need them. Take a look at this post for further details.

like image 29
Óscar López Avatar answered Sep 21 '22 17:09

Óscar López


You've attempted to write to the output stream before you attempt to listen on the input stream, so it makes sense that you're seeing nothing. For this to succeed, you will need to use separate threads for your two streams.

i.e.,

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();
   }
}

And you really shouldn't ignore the error stream either but instead should gobble it, since ignoring it will sometimes fry your process as it may run out of buffer space.

like image 108
Hovercraft Full Of Eels Avatar answered Sep 21 '22 17:09

Hovercraft Full Of Eels