【发布时间】: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