如何从Java的流程输出中实时读取BufferedReader?

时间:2019-06-19 15:20:06

标签: java javafx processbuilder

我正在尝试使用BufferedReader从进程中实时读取数据并将其重定向到TextArea。但是,我注意到,当进程运行.bat时,它倾向于冻结并导致JavaFX TextArea滞后。运行的“ .bat”字段打印出.....一行,以指示进度,我相信这是失败的地方。 我有一个想法,让程序等待一定的时间,然后执行,但是因为它全部都在一行上,所以它也会失败。请帮助

代码:

 while(iterator.hasNext()) {
    Map.Entry mentry = (Map.Entry)iterator.next();
    String taskPath = " /k d: && cd DATA\\Virtualization\\Users && ESXRun.bat";
    ProcessBuilder pb = new ProcessBuilder("cmd",taskPath);
    Process process = pb.start();
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

    String s = "";
    // read the output from the command

    while ((s = stdInput.readLine()) != null) {
        //TextArea
        cliLog.appendText(s);                       
        cliLog.appendText("\n");
    }
    process.waitFor();
    process.destroy();
}

1 个答案:

答案 0 :(得分:2)

这只是演示问题的概念。 您必须对其进行自定义并处理异常。

public class TextAreaBash extends Application implements Runnable {

    private final TextArea textArea = new TextArea();

    public static void main(final String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(final Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(new VBox(textArea), 300, 200));
        primaryStage.show();
        ping();
    }

    public void ping() {
        new Thread(this).start();
    }

    @Override
    public void run() {
        try {
            final ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", "ping -a www.google.com -n 10");
            final Process process = processBuilder.start();
            final InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
            while (appendText(inputStreamReader)) {
                ;
            }
            process.waitFor();
            process.destroy();
        } catch (final Exception ex) {
            ex.printStackTrace();
        }
    }

    private boolean appendText(final InputStreamReader inputStreamReader) {
        try {
            final char[] buf = new char[256];
            final int read = inputStreamReader.read(buf);
            if (read < 1) {
                return false;
            }
            Platform.runLater(() -> {
                textArea.appendText(new String(buf));
            });
            return true;
        } catch (final IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

ping TextArea