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...

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Timo
  • 49
  • 1
  • 1
  • 4

1 Answers1

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();
}
}
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • 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 Jul 12 '17 at 07:56
  • @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. – Antoniossss Jul 12 '17 at 08:29
  • 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. – Antoniossss Jul 12 '17 at 10:02
  • To create `String` from `int` (that is actually a `char`) - `String.valueOf((char)c);`. Its fine on small scale but not at large. – Antoniossss Jul 12 '17 at 10:14