0

I'm writing a Java program that is used to call a PHP script in set intervals. The PHP script outputs a lot of data, and it is the client's requirement that the Java program displays all the PHP script's output while the script runs.

The method I'm using is:

Runtime.getRuntime().exec(new String[]{"php", "file.php"});

Then using an InputStreamReader to grab output, primarily using examples from here. The problem I'm having is that the stream reader only outputs the data once the PHP script exits (which makes sense considering how the output is looped through).

How would I go about printing the script's output live while the script is running?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
aggregate1166877
  • 2,196
  • 23
  • 38
  • 2
    It can be easier to use a `ProcessBuilder` to construct the `Process`. It allows easy merging of the `System.out` & `System.err`. +1 on referring to the Java World article. Since it solves 60% of questions where people **don't** mention it, I feel compelled to link. ;) – Andrew Thompson Sep 13 '12 at 10:54
  • 1
    Good idea. I was actually thinking to do a `ProcessBuilder.redirectOutput()` to a file and trying to tail it – aggregate1166877 Sep 14 '12 at 07:59

2 Answers2

5

I did this by reading the output from a separate thread:

  Process p = Runtime.getRuntime().exec(commands);
  final InputStream stream = p.getInputStream();
  new Thread(new Runnable() {
    public void run() {
      BufferedReader reader = null;
      try {
        reader = new BufferedReader(new InputStreamReader(stream));
        String line = null;
        while ((line = reader.readLine()) != null) {
          System.out.println(line);
        }
      } catch (Exception e) {
        // TODO
      } finally {
        if (reader != null) {
          try {
            reader.close();
          } catch (IOException e) {
            // ignore
          }
        }
      }
    }
  }).start();
Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • 2
    While the general aproach is your answer is correct, it's rather shaky regarding text encodings. If Java uses a different default encoding than the external process, most non-ASCII characters will replaced with a character from a different encoding. And if UTF-8 is used, then you're likely to cut a multi-byte encoding sequence into two parts sooner or later. Then an encoding exception will be thrown and the thread will exit. – Codo Sep 13 '12 at 10:48
  • @Dan I like the idea behind your answer, but it still only displays the script output once the PHP script **exits**. Whenever the PHP script prints out code, i want it to show instantly. Otherwise the script runs for about 2 minutes and outputs a few hundred lines all at once. – aggregate1166877 Sep 13 '12 at 12:41
  • +1 **This answer the question 100%** taking in consideration what @Dan said. Came here for the same issue as op and a copy/paste worked just fine – mraistlin Mar 11 '16 at 15:32
0

For now I decided to go with Andrew Thompson's suggestion:

ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();

InputStreamReader istream = new  InputStreamReader(process.getInputStream());
BufferedReader br = new BufferedReader(istream);

String line;
while ((line = br.readLine()) != null){
   System.out.println(line);
}

process.waitFor();

This is still not what I'm looking for though, so for now I'm leaving the question unanswered.

aggregate1166877
  • 2,196
  • 23
  • 38