Java ProcessBuilder - 立即获取输出

标签 java processbuilder

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

它工作正常,但我希望 EXE 的输出立即出现在我的 JAVA 程序的文本区域中。

目前,我在“ping”命令完全完成后得到输出(因此 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 运行后才能得到完整的输出。如果我调试,我会得到这些行(逐行)。所以可能还有另一个问题......

最佳答案

确实,我尝试了您的示例,它立即输出流,但我没有使用文本区域,而是使用控制台输出。 您的代码到底是如何被调用的?也许它与 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();
}
}

关于Java ProcessBuilder - 立即获取输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45050390/

相关文章:

java - Lejos EV3 "Null Pointer Exception",但我不知道如何修复它

java - 在Quartz Scheduler集群中设置固定节点

java - Appengine 无法从数据存储中检索实体

java - "Program Files"命令实习生未找到 CMD

java - 在 Java JDK 1.6 中,我需要运行一个接受重定向输入的可执行文件

java - 使用 Java ProcessBuilder 运行 Jar 会产生空输出

java - 如何将S3ObjectInputStream转换为Base64 url​​?

Java 子进程额外输出到控制台

java - 使用 ProcessBuilder 向外部进程发送命令

java - J2EE连接远程Oracle DB表