我将使用
这些命令支持自定义采样间隔。如果我向外部命令添加一个采样间隔,例如
当我使用NIO服务器运行命令并使用SocketChannel将输出发送给客户端时,问题变得更加严重...(在服务器显示第一个输出后,我的客户端需要等待另外20秒才能获得输出,这是进程启动后20秒)。
我注意到输出延迟的长度与我设置的命令间隔有关。
那么为什么ISR不能实时读取输出呢?
以下是一个简单的测试代码片段以演示我的问题:
ProcessBuilder
来运行一些外部命令,例如Linux中的ifstat
或vmstat
。这些命令支持自定义采样间隔。如果我向外部命令添加一个采样间隔,例如
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
会延迟显示头部?
ifstat 20 | cat
,这样它就会写入管道而不是控制台。 - Peter Lawreyifstat 120
... - Dante WWWW