当前位置: 首页 > 知识库问答 >
问题:

JavaProcessBuilder-立即获取输出

梁丘亦
2023-03-14

我想在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运行后才能得到这个完整的输出。如果我调试,我会得到这些行(一行一行)。所以可能还有另一个问题。。。

共有1个答案

秦炜
2023-03-14

为了真实,我尝试了你的例子,它立即输出流,但是我没有使用文本区域,而是控制台输出。你的代码到底是如何被调用的?也许它与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中的条件运算符语句中,是否同时评估true和false参数? 所以下面的代码可以抛出NullPointerException 问题答案: 由于您需要该规范,因此在这里(摘自§15.25Conditional Operator?: ,这部分的最后一句话): 对于条件表达式的特定评估,不会评估未选择的操作数表达式。

  • 示例PRUNKR:https://plnkr.co/edit/NZwb3ol8CbZFtSc6Q9zm?p=preview 我知道RxJS(5.0 beta.4)有以下3种节流方法: ,和 我正在寻找的行为是默认情况下在上执行的行为: 理论上,这应该看起来像: 但是 如果在节流超时时发出,则从不给我最后一个值 我可以结合任何RxJS方法来实现所描述的行为吗?

  • 问题内容: 我想在我的C程序中读取箭头按键,并用其他字符串替换它们(立即在终端本身中)。我正在尝试在UNIX终端中实现bash历史记录功能。我写了这段代码。 但是,这不起作用,因为终端等待换行符或EOF将输入缓冲区发送到stdin。因此,我必须按Enter / Return键来分析用户输入。 用户在此回答中提到要使用,但这将替换所有默认的终端行为(例如,退格键,删除等)。 因此,如果检测到箭头按键

  • 问题内容: 我使用Hibernate 5.2.5(如果重要的话,也可以使用kotlin和spring 4.3.5),并且我希望延迟加载类的某些字段。但是问题是所有字段都立即加载,我没有任何特殊的Hibernate设置,也没有使用Hibernate.initialize()。 这就是我的查询方式 TaskRepoImpl: TaskService: 并输出: 请告知我的代码出了什么问题以及如何使Hi

  • 我试图在更改选择选项后立即获得_POST美元的价值,而无需提交表单。 我使用onchange=“this.form.submit”和捕获$\u POST数组中的值来执行此操作,但我希望在每次选项更改时不提交表单

  • 编辑:下面是list_item_view.xml