0

i want to get bat file output real time using java process builder.but the problem is i'm not getting any output .how can i improve this to get output

this is my javacode

void pingIp() throws InterruptedException, IOException {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String[] commands = {"C:\\Users\\Madhawa.se\\Desktop\\addonapp\\matrix.bat"};

                ProcessBuilder process = new ProcessBuilder(commands);
                process.redirectErrorStream(true);

                Process shell = process.inheritIO().start();

                //shell.waitFor();
                BufferedReader stdInput = new BufferedReader(new InputStreamReader(shell.getInputStream()));
                BufferedReader stdError = new BufferedReader(new InputStreamReader(shell.getErrorStream()));

                // read the output from the command
                System.out.println("Here is the standard output of the command:\n");
                while ((s = stdInput.readLine()) != null) {
                    System.out.println(":" + s);
                }

                // read any errors from the attempted command
                System.out.println("Here is the standard error of the command (if any):\n");
                while ((s = stdError.readLine()) != null) {
                    System.out.println(":" + s);
                }
            } catch (IOException ex) {
                Logger.getLogger(pingIo.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    });
    t.start();

}

my actual bat file is complex so for example i use following bat file.this bat file print random numbers in intervals[1 s].so i want to get output in my java console in real time

::matrix interval //matrix.bat
@echo off
color 0a
:top
echo %random%%random%%random%%random%
ping 1.1.1.1 -n 1 -w 1000 > nul
goto top

thanks!

Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60
  • Don't use shell.waitFor(), it's possible that some processes will never exit until the output buffer is drained. Instead, consider using one or more threads to read the output/error streams and once started, use shell.waitFor to stall the code at that point – MadProgrammer Dec 28 '14 at 06:35
  • Something like [this example](http://stackoverflow.com/questions/23716144/execute-java-file-with-runtime-getruntime-exec/23716208#23716208) for instance – MadProgrammer Dec 28 '14 at 06:37
  • @MadProgrammer thanks for the responce actually after i removed the line waitfor i got output `Here is the standard output of the command` but still no output from batfile.and your example seems correct for me.i'm testing it – Madhawa Priyashantha Dec 28 '14 at 06:39
  • 1
    You could also try removing the usage of `inheritIO` as I've found that this can sometimes prevent the output from been read from some reason – MadProgrammer Dec 28 '14 at 07:25
  • @MadProgrammer i used inheritIo because it was suggested for my question http://stackoverflow.com/questions/26489106/runtime-getruntime-failed-to-get-output-same-time-but-later .actually this question based on it.i just removed inheritIo awesome now it's working nicely .if you supply this comment as answer i will accept – Madhawa Priyashantha Dec 28 '14 at 07:30
  • Sometimes it's a good thing, sometimes it's not ;) – MadProgrammer Dec 28 '14 at 07:33
  • 1
    @MadProgrammer (but I'm sure you know that) and to Fast Snail: A stream going through a pipe is usually buffered on the sender's side. This will ultimately prevent the lines from arriving in real time. Stream i/o was never destined to be used for real time process communication. -- Not sure what the *real* bat should do, but it would be better to call the programs called from the bat from the Java program - then you'd get the responses quickly - at least when the individual subprocesses end. – laune Dec 28 '14 at 07:34
  • @laune That's a great suggestion – MadProgrammer Dec 28 '14 at 07:36
  • @laune thanks for your response.i will learn more about it – Madhawa Priyashantha Dec 28 '14 at 07:38

1 Answers1

2

inheritIO needs to be used in places where output is not been read through normal means. When used incorrectly it can prevent output from been read from the process.

You should also read the output/error streams in a separate thread and use waitFor AFTER you've started those threads. This allows you to block at that point in the code, but still process the streams, as some processes can stall if the output buffer is not read

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366