Java ProcessBuilder - 立即获取输出

时间:2017-07-12 06:51:11

标签: java processbuilder

我想在JAVA程序中执行EXE文件。

它工作正常,但我想在我的JAVA程序的textArea中立即输出EXE。

目前我在" ping" -Command完全结束后得到输出(因此JAVA程序挂起约3秒)。但我想立即得到结果......

我做错了什么?

    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);
    }

突击队倒退。

我想使用这个程序: https://iperf.fr/iperf-download.php

输出如下:

    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.

iperf运行后,我仍然只能得到这个完整的输出。如果我调试,我得到线(逐行)。所以可能还有另一个问题......

1 个答案:

答案 0 :(得分:2)

为了成为现实,我尝试了你的例子,它立即输出流,但我没有使用文本区域,但控制台输出。 您的代码究竟是如何调用的?也许它与GUI重绘管理器有关 - 它是从EDT调用的吗?如果不是,这可能会导致延迟。

尝试做这样的事情:

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

当您使用后台任务时(但您不知道),您应该使用专用实用程序来实现此SwingWorker https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html。作为奖励,这里是完整的例子,你可以自己跑。它使用swing worker来完成后台工作并在EDT上更新GUI

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();
}
}