如何在外部程序中处理不同的stdout行为?

时间:2012-07-16 14:34:58

标签: java stdout bufferedreader stderr external-process

您好我正在尝试从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秒生成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

假设我在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读取它时,只要程序仍在运行({I}},我就会inputtext(我已经通过打印输出文本来测试它)。当我按null时,BufferedReader将突然填充所有待处理的标准输出。

如何实时阅读server2.exe的ctrl-C

2 个答案:

答案 0 :(得分:3)

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

虽然可能有ways to work around this,但我会在server2源代码中解决此问题。每当该应用程序写入每秒一次的输出时,之后刷新其输出流。也许有一些选项可以启用该行为。如果没有,并且该程序的源代码不在您的控制之下,请开发人员添加刷新,以便更好地集成。

答案 1 :(得分:0)

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

System.out.flush()

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