gpt4 book ai didi

java - 为什么 InputStreamReader 不实时读取进程的输出?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:30:39 28 4
gpt4 key购买 nike

我正在尝试使用 ProcessBuilder 运行一些外部命令,例如 Linux 中的 ifstatvmstat

此类命令支持自定义采样间隔。如果我在外部命令中添加一个采样间隔,例如 ifstat 20,那么命令将输出如下:

coolcfan@coolcfan-PC:~$ ifstat 20
eth0 wlan0 vmnet1 vmnet8
KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out

20秒后

   41.29      1.06      0.36      0.00      0.00      0.00      0.00      0.00

又过了20秒

   16.67      0.58      0.38      0.00      0.00      0.00      0.00      0.00

但是,当我使用我的 Java 代码运行命令时,将在 20 秒后读取输出的第一部分,如下所示:

Start running "ifstat 20"

20秒后

       eth0               wlan0               vmnet1              vmnet8      
KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out
66.61 1.73 1.29 0.01 0.00 0.00 0.00 0.00

当我使用 NIO 服务器运行命令并使用 SocketChannel 将输出发送到客户端时,问题更加严重......(我的客户端需要再等待 20 秒才能从一个接一个服务器获取输出显示进程开始后 20 秒的第一个输出)

而且我注意到输出的延迟时间长短与我给命令设置的时间间隔有关。

那么ISR为什么不实时读取输出呢?

演示我的问题的简单测试代码片段:

public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder();

pb.command("ifstat 20".trim().split(" "));

Process p = null;

System.out.println("Start running \"ifstat 20\"");

try {
p = pb.start();

char[] buf = new char[512];

InputStreamReader isr = new InputStreamReader(p.getInputStream());

int count = -1;

while ((count = isr.read(buf, 0, buf.length)) != -1) {
System.out.print(new String(buf, 0, count));
}
}
catch (IOException ioe) {
}
}

更新:

正如 Peter 的评论,这不是与 Java 相关的问题。这是一个管道延迟

但是我还是不明白,为什么vmstat 20 | cat 没有这个延迟,而 ifstat 20 | cat 会延迟显示头部吗?

最佳答案

确实如此。

被延迟的是过程的输出。 STDIO 进行缓冲,这根据 stout 是或不是终端而有所不同。

关于java - 为什么 InputStreamReader 不实时读取进程的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14456605/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com