【问题标题】:How to read from InputStream that is constantly updating如何从不断更新的 InputStream 中读取
【发布时间】:2020-10-28 14:23:55
【问题描述】:

我正在用 Java 开发一个应用程序,它基本上只是通过 GUI 收集用户的输入,并将这些数据提供给执行一些文件系统操作的 python 脚本。这个 python 脚本是通过 Java Process 类执行的。每个脚本只是将一些数据打印到它的标准输出,当我调用 process.getInputStream() 时,我会在主 java 应用程序中解析这些数据。

我有一个 python 脚本,它基本上在日志文件上执行tail -f 并逐行打印。我的 java 程序使用来自该特定进程的 InputStream 解析此输出。但是,我觉得它非常慢。我将此日志附加到 JavaFX TextArea,在执行 python 脚本后,我的 java 程序开始拾取任何东西通常需要大约 20 秒,但是当我自己运行 python 脚本时,它会按预期运行。

到目前为止我已经尝试过:使用缓冲阅读器解析它:

InputStream is = this.currentTask.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line;
while (this.currentTask.isAlive()){
   line = reader.readLine();
   if (line != null){
           final String finalLine = line;
           // JavaFX stuff so that the appending is on the main thread
           Platform.runLater(() -> output.appendText(finalLine + "\n"));
           continue;
   }
   // wait for the log to be updated 
   Thread.sleep(100);
}

当我使用调试器单步调试时,它会在line = reader.readLine(); 部分卡住很长时间。将读取方法切换为 BufferedReader 提供的另一种读取方法(如使用指定的 char 缓冲区读取)根本没有帮助。

知道可能是什么问题吗?

编辑:添加了 MCVE

Java 程序:

public static void main(String[] args) {
    Process process = null;
    try {
        process = Runtime.getRuntime().exec("python" + " " + "main.py");
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        InputStream is = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
        String line;
        while (process.isAlive()){
            line = reader.readLine();
            if (line != null){
                System.out.println(line);
                continue;
            }
            // wait for the log to be updated
            Thread.sleep(100);

        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
}

Python 程序:

import time

i = 0
while True:
    print("Output ", i)
    i += 1
    time.sleep(0.5)

我注意到,当我从 python 脚本中删除睡眠时,整个事情都可以正常工作。但是,在真正的应用程序中,需要睡眠。

【问题讨论】:

  • 也许如果你逐个字符而不是逐行阅读它,你会获得更好的用户体验。
  • reader.readline() 将阻塞直到有完整的文本行(即以换行符或流结尾的文本)可用。因此,您的 python 脚本很可能正在生成输出但没有发送换行符,或者可能没有刷新整个输出。 (另请注意,由于readline() 阻塞,您的Thread.sleep(...) 是多余的。)按照建议,创建并发布一个minimal reproducible example,其他人可以使用它来重现该问题。 (一个简单的 JavaFX 应用程序和重现问题的最简单的 python 脚本就足够了。)
  • 知道可能是什么问题吗?我不喜欢猜测,请提供 MCVE 或 @kleopatra 指出的 How to create a Minimal, Reproducible Example。另请注意,拥有 MCVE 可以让其他人有效地回答您的问题。
  • 不要忘记接受您自己对问题的回答,这样该问题就不会再显示为未回答的问题。

标签: java python javafx inputstream command-pattern


【解决方案1】:

好的,我刚刚解决了。感谢this SO 问题。

Java 不是问题,python 只是没有足够频繁地刷新它的输出,Java 没有什么可读取的,仅此而已。我必须手动刷新我的 python print() 函数,一切正常。

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2021-02-14
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多