嗨,我正在尝试从Java程序执行外部程序,并读取stdout消息in real time
,而不等待程序退出。然而,我发现在不同的.exe程序中有不同的stdout行为,我不知道如何处理它
示例1:
server1.exe是一个控制台程序。当我运行它时,它会持续监听一个端口。当客户端连接到它时,每1秒会生成1行stdout
输出。除非我按"ctrl-C",否则它不会退出。
在命令提示符下,我运行以下命令:
server1.exe > stdout.out 2> stderr.err
当客户端连接到它时,我发现stdout.out file
会实时更新。即使server1.exe仍在运行,我也可以打开stdout.out file
并实时读取stdout输出。
示例2:
与server1.exe类似,server2.exe也是一个控制台程序。当我运行它时,它也会持续监听一个端口。当客户端连接到它时,每1秒会生成一行stdout输出。除非我按"ctrl-C",否则它不会退出。
在命令提示符下,我运行以下命令:
server2.exe > stdout.out 2> stderr.err
尽管客户端已经连接到server2.exe,但我发现stdout.out file
是空的。只要server2.exe仍在运行,就不会向stdout.out file
写入stdout。real time
中未更新该文件。当我按下ctrl-C
时,它突然将许多行输出写入stdout.out file
。
假设我在t=11按下ctrl-C
,它将把t=1到t=11的所有stdout输出写入stdout.out file
。在此之前,在t=10时,stdout.out
文件为空。
示例2中的程序给我带来了问题,因为我无法在Java程序中read the stdout in real time
。我的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秒看到控制台窗口上打印的stdout输出。但是,当我尝试使用inputtext = input.readLine()
从Java中读取它时,只要程序仍在运行,inputtext
就会是null
(我已经通过打印输入文本对其进行了测试)。当我按下ctrl-C
时,BufferedReader将突然充满所有挂起的stdout输出。
如何实时读取server2.exe的stdout
?
按照您描述的方式,在您的第二台服务器中发生了一些缓冲。服务器可能决定在内部缓冲输出,除非它连接到实时交互式控制台窗口。
虽然可能有一些方法可以解决这个问题,但我会在server2
源代码中解决这个问题。每当该应用程序每秒写入一次输出时,都应该随后刷新其输出流。也许有一些选择可以实现这种行为。如果没有,并且该程序的源不在您的控制范围内,请要求开发人员添加刷新,以实现更好的集成。
简而言之:您需要刷新缓冲区。
System.out.flush()
您需要在这些流上写入每一块相关数据后进行此操作,请尝试在每一行打印后进行此项操作。