3

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

4

1 に答える 1

2

します。

遅れているのはプロセスのアウトプットです。STDIO はバッファリングを行いますが、これはスタウトが端末であるかどうかによって異なります。

于 2013-01-23T02:29:50.160 に答える