【问题标题】:Reading from BufferedReader从 BufferedReader 读取
【发布时间】:2016-06-01 13:24:26
【问题描述】:

我正在尝试在终端上执行命令。使用

        ProcessBuilder builder = new ProcessBuilder("/bin/bash");
        builder.redirectErrorStream(true);
        Process process = builder.start();
        OutputStream stdin = process.getOutputStream();
        InputStream stdout = process.getInputStream();

        reader = new BufferedReader(new InputStreamReader(stdout));
        writer = new BufferedWriter(new OutputStreamWriter(stdin));

我将使用这个 reader 和 writer 来不断地与进程进行通信。

我正在使用以下循环读取

        while ((line = reader.readLine()) != null) {
        System.out.println("line);
        }

问题:这里的问题是,当阅读器开始从缓冲区读取时,它会永远处于 while 循环中。它永远不会退出。

我试图把阅读放在一个线程中

public void run() {
        try {
            String line;
            outputText = "";
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            Logger.getLogger(ThreadReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

但现在我无法控制阅读器何时开始阅读和结束阅读。

目标:我需要执行一个命令并读取输出,然后读取下一个命令。

【问题讨论】:

  • 为什么您无法控制阅读器何时启动?那是你开始线程的时候吗? (或者最好将其安排在线程池中)。当进程终止或关闭其输出/错误流时,您的阅读器会停止。如果这个过程不这样做,那么你的读者就不会停止。
  • 尝试使用某个流结束标记来告诉读者何时需要完成(或休息一下)。否则它将无限期地等待新输入,因为它不知道其他进程是否已完成写入流。
  • “我需要执行一个命令并读取输出……”解释一下“读取输出”的实际含义。读取一行输出?读五行?读取所有剩余的输出?
  • 检查 line.length() != 0

标签: java process bufferedreader


【解决方案1】:

您的 Java 程序正在与外部交互进程通信。它只有进程的输出和错误流可用于确定如何从任何给定点继续。如果您希望它识别输出的细分,例如对单个命令的响应,那么您需要教它这些细分的边界是什么样的。

您可以通过多种方式解决问题。例如,如果外部程序在准备好接受新命令时发出提示,那么观察该提示似乎很自然。或者,也许您可​​以调整程序的输入,使其在每个命令输出的末尾产生一个可识别的标记。

还要考虑这是一个已解决的问题(很多次)。用于交互式程序的通用脚本的规范实用程序是称为“Expect”的 Tcl 程序。它启发了许多语言中的类似工作,包括 Java 中的许多。 Google 在前五首热门歌曲中给了我三个不同的例子,但我对其中任何一个都没有具体经验,所以我不推荐。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2013-10-30
    • 2019-01-09
    • 2014-09-26
    • 1970-01-01
    • 2019-01-01
    • 2014-02-09
    相关资源
    最近更新 更多