0

I am executing an executable with a command line argument using ProcessBuilder and I am trying to read the output using a BufferdReader. However, when I print out the input stream of the process, it seems I am first printing out the output, then the input as well.

For example, I am trying to execute "my_command -an-option /path/to/file", and when I print out the buffered reader, I am printing out the output followed by the contents of the my file at /path/to/file. I guess it makes sense that the input stream is reading in my inputp and the output,

public static void d(String file) throws Exception {
    ProcessBuilder builder = new ProcessBuilder("my_command", "-an-option", file);
    builder.redirectErrorStream(true);

    Process process = builder.start();
    BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
    process.waitFor();

    String s = null;
    while ((s = in.readLine()) != null) System.out.println(s);

    in.close();
}

public static void main(String[] args) {
    d("/path/to/file");
}

Does anyone know how to make it only print out the output? I want to save the output to a string or something and parse it, etc.

gruuuvy
  • 2,028
  • 4
  • 31
  • 52
  • No, this doesn't make sense. The content of the file can only be printed if the spawned process is writing it to standard output (or standard error, since you've redirected it). In other words, your description indicates that `my_command` doesn't work the way you assume it does. – erickson Mar 26 '14 at 22:12
  • So, `my_command` is actually just `opt`... but `opt` doesn't print out the output of the input file. – gruuuvy Mar 26 '14 at 22:14
  • 1
    Also, if `my_command` writes too much, you will have a deadlock, because its output stream will block when the pipe fills up. Unless you *know* that the process will never fill the pipe, you need to consume its output before calling `process.waitFor()`. – erickson Mar 26 '14 at 22:15
  • LLVM `opt`? What `opt` are you talking about? – erickson Mar 26 '14 at 22:16
  • Well, that really is a puzzle. You aren't opening the file in your Java program; the only thing that reads the file is `opt`. So if you see the content of the file, it must have come from `opt`. Is the option `-debug` or something? Are you loading any plugins that might output extra info? What happens when you run `opt` from the command line with the same arguments? – erickson Mar 26 '14 at 22:26
  • The option is `-print-callgraph`. When I run the `opt` with the same arguments on the command line (`opt -print-callgraph file.bc`), it does not print the content of `file.bc`. But when I use my program to run it, it also prints the byte code contents afterwards of `file.bc`. – gruuuvy Mar 26 '14 at 22:28
  • Hmm, not sure. Comment out the `builder.redirectErrorStream(true)` line and see if that helps. – erickson Mar 26 '14 at 22:32
  • `builder.redirectErrorStream(true)` is the line that is allowing it to capture the output. The output gets directed to the error stream. If I comment it out, then only the byte code stuff is printed out. – gruuuvy Mar 26 '14 at 22:40
  • Then don't redirect. Replace `process.getInputStream()` with `process.getErrorStream()`. And add a call to `builder.redirectOutput(new File("/dev/null"))` so that `opt` doesn't block. – erickson Mar 26 '14 at 22:48
  • So I fixed the problem by doing exactly what you said, using `process.getErrorStream()`. Thank you! – gruuuvy Mar 26 '14 at 23:01
  • Is there a way to redirect output to /dev/null using Java 6? I don't have Java 7. – gruuuvy Mar 29 '14 at 21:46

0 Answers0