0

您好我正在尝试从 Java 程序执行外部程序并读取标准输出消息in real time,而无需等待程序退出。但是,我发现在不同的 .exe 程序中有不同的 stdout 行为,我不知道如何处理它。

示例 1:
server1.exe 是一个控制台程序。当我运行它时,它会不断地监听一个端口。当客户端连接到它时,它将stdout每 1 秒生成 1 行输出。除非我按“ctrl-C”,否则它不会退出。

在命令提示符下,我运行这个:

server1.exe > stdout.out 2> stderr.err

当客户端连接到它时,我发现它stdout.out file会实时更新。即使 server1.exe 仍在运行,我也可以stdout.out file实时打开并读取标准输出。

例2:
与server1.exe类似,server2.exe也是一个控制台程序。当我运行它时,它也会不断地监听一个端口。当客户端连接到它时,它将每 1 秒生成 1 行 stdout 输出。除非我按“ctrl-C”,否则它不会退出。

在命令提示符下,我运行这个:

server2.exe > stdout.out 2> stderr.err

即使客户端已连接到 server2.exe,我发现它stdout.out file是空的。只要 server2.exe 仍在运行,就不会将标准输出写入stdout.out file. 该文件未在real time. 当我按下ctrl-C时,它突然将许多行输出写入stdout.out file

假设我ctrl-C在 t=11 时按下,它将把从 t=1 到 t=11 的所有 stdout 输出写入stdout.out file. 在此之前,在 t=10,stdout.out文件为空。


示例 2 中的程序给我带来了问题,因为我无法read the stdout in real time在我的 Java 程序中使用。我的java程序如下:

process = Runtime.getRuntime().exec(command);

input = new BufferedReader(new InputStreamReader(process.getInputStream()));

String inputtext = null;

while ((inputtext = input.readLine()) != null)
{
    //print out the text in Real Time, when the .exe program is still running
}

我可以知道为什么示例 2 中的程序不会生成stdout output,除非我按ctrl-C吗?

奇怪的是,当我在控制台窗口中手动运行该程序时,我可以看到控制台窗口每 1 秒打印一次标准输出输出。但是当我尝试使用 Java 从 Java 中读取它时,inputtext = input.readLine()只要程序仍在运行(我已经通过打印输入文本对其进行了测试)。当我按下时,BufferedReader 将突然被所有待处理的 stdout 输出填充。inputtextnullctrl-C

如何stdout实时读取 server2.exe?

4

2 回答 2

3

您描述事物的方式,在您的第二台服务器中发生了一些缓冲。服务器可能决定在内部缓冲输出,除非它连接到实时交互式控制台窗口。

虽然可能有办法解决这个问题,但我会在server2源代码中解决这个问题。每当该应用程序写入其每秒一次的输出时,它应该在之后刷新其输出流。也许有一些选项可以启用该行为。如果没有,并且该程序的来源超出您的控制范围,请要求开发人员添加刷新,以便更好地集成。

于 2012-07-16T14:48:28.740 回答
0

简而言之:您需要刷新缓冲区。

System.out.flush()

您需要在这些流上写入每一块相关数据之后执行此操作,尝试在每行打印后执行此操作。

于 2012-07-20T11:41:24.183 回答