1

i want to execute an EXE-file in a JAVA-Program.

It works fine, but i want the output of the EXE immediately in a textArea of my JAVA-Program.

Currently i get the output after the "ping"-Command has finished completely (so the JAVA-program hangs for about 3 seconds). But i want to have the result immediately...

What am i doing wrong?

    ProcessBuilder pb = new ProcessBuilder().command("C:\\Windows\\SysWOW64\\PING.EXE", "127.0.0.1");
    pb.redirectErrorStream(true);

    Process process = pb.start();

    InputStream processStdOutput = process.getInputStream();
    Reader r = new InputStreamReader(processStdOutput);
    BufferedReader br = new BufferedReader(r);
    String line;
    while ((line = br.readLine()) != null) {
//      System.out.println(line); // the output is here
        textArea.append(line);
    }

commando backwards.

Well i want to use this program: https://iperf.fr/iperf-download.php

Output looks like:

    Connecting to host 10.1.100.34, port 5201
[  4] local 172.16.12.33 port 63802 connected to 10.1.100.34 port 5201
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   1.00-2.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   2.00-3.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   3.00-4.00   sec   112 MBytes   940 Mbits/sec                  
[  4]   4.00-5.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   5.00-6.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   6.00-7.00   sec   112 MBytes   940 Mbits/sec                  
[  4]   7.00-8.00   sec   112 MBytes   944 Mbits/sec                  
[  4]   8.00-9.00   sec   112 MBytes   940 Mbits/sec                  
[  4]   9.00-10.00  sec   112 MBytes   944 Mbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec                  sender
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec                  receiver

iperf Done.

Still i only get this complete output after iperf has run. If i debug, i get the lines (line by line). So there might be another problem...

7
  • maybe the buffer in BufferedReader is causing it to be buffered? Commented Jul 12, 2017 at 7:01
  • Dont use BufferedReader for this, try to read directly from Reader r Commented Jul 12, 2017 at 7:01
  • Also what does it mean that it hangs? You mean that window pops up with blank text area and after 3 seconds text showes into it? You know you have to use threads for that right? Commented Jul 12, 2017 at 7:10
  • It could be because you shouldn't update Swing components from another thread. Take a look at this question: stackoverflow.com/q/7229284/13075 Commented Jul 12, 2017 at 7:11
  • @Henrik already in the answer Commented Jul 12, 2017 at 7:11

1 Answer 1

3

For to be true, I tried your example and it outputs stream right away, but i didnt use text area for that, but console output. How exactly is your code invoked? Maybe it is related to GUI repaint manager - Is it invoked from EDT? If not, this may cause the delay.

Try to do something like this:

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            area.append(line);
        }
    });

As you are using background task (but you are not aware of that) you should use dedicated utility for this called SwingWorker https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html. As a bonus here is complete example you can run yourself. It uses swing worker to do a background job and updates GUI on EDT

public class LetsPing {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.setSize(300, 300);
    frame.setLocationRelativeTo(null);

    JTextArea textArea = new JTextArea();
    frame.add(textArea, BorderLayout.CENTER);
    frame.setVisible(true);

    new SwingWorker<Void, String>() {
        @Override
        protected Void doInBackground() throws Exception {
            ProcessBuilder pb = new ProcessBuilder().command("C:\\Windows\\SysWOW64\\PING.EXE", "127.0.0.1");
            pb.redirectErrorStream(true);
            Process process;
            process = pb.start();
            InputStream processStdOutput = process.getInputStream();
            Reader r = new InputStreamReader(processStdOutput);
            BufferedReader br = new BufferedReader(r);
            String line;
            while ((line = br.readLine()) != null) {
                publish(line);
            }
            return null;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String line : chunks) {
                textArea.append(line);
                textArea.append("\n");
            }
        }
    }.execute();
}
}
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your code. It works fine with the ping command. But when i use another command like "iperf3.exe -c 10.15.100.34" i have the same behavior as before. I only get the complete output, after command has finished. (about 4-5 seconds).
@Timo idk what is the normal output of iperf3 so no help here. Maybe it is using different charset for new lines etc. Start with using plain readers insteed of buffered one.
Ofc because read returns character code. But at least you know now that buffering was the issue here. Dont pass code into comments as it is pain to read. You can edit question or something.
To create String from int (that is actually a char) - String.valueOf((char)c);. Its fine on small scale but not at large.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.