LinuxなどProcessBuilder
の外部コマンドを実行するために使用しようとしています。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
のに、頭を表示するのが遅れるのですか?