0

こんにちは私はJavaプログラムから外部プログラムを実行in real timeし、プログラムが終了するのを待たずにstdoutメッセージを読み込もうとしています。ただし、.exeプログラムごとに異なるstdoutの動作があることがわかり、その処理方法がわかりません。

例1:
server1.exeはコンソールプログラムです。実行すると、ポートで継続的にリッスンします。クライアントが接続されると、stdout1秒ごとに1行の出力が生成されます。「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

stdout.out fileクライアントがserver2.exeに接続していても、空であることがわかりました。server2.exeがまだ実行されている限り、stdoutはに書き込まれません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のプログラムでread the stdout in real timeは、Javaプログラムを使用できないため、問題が発生しています。私の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
}

stdout outputを押さないと、例2のプログラムが生成されない理由を教えてくださいctrl-C

奇妙なことに、コンソールウィンドウでそのプログラムを手動で実行すると、1秒ごとにコンソールウィンドウにstdout出力が出力されます。inputtext = input.readLine()しかし、を使用してJavaから読み取ろうとすると、プログラムがまだ実行されている限り長くinputtextなりますnull(入力テキストを出力してテストしました)。を押すctrl-Cと、BufferedReaderが突然すべての保留中のstdout出力でいっぱいになります。

stdoutserver2.exeをリアルタイムで読み取るにはどうすればよいですか?

4

2 に答える 2

3

物事を説明する方法では、2番目のサーバーでバッファリングが発生しています。サーバーは、ライブのインタラクティブコンソールウィンドウに接続されていない限り、出力を内部でバッファリングすることを決定する場合があります。

これを回避する方法があるかもしれませんが、私はserver2ソースコードでこれに対処します。そのアプリケーションが1秒に1回の出力を書き込むときはいつでも、後で出力ストリームをフラッシュする必要があります。おそらく、その動作を有効にするためのいくつかのオプションがあります。存在しない場合、およびそのプログラムのソースが制御できない場合は、より良い統合を可能にするために、開発者にフラッシュを追加するように依頼してください。

于 2012-07-16T14:48:28.740 に答える
0

簡単に言うと、バッファをフラッシュする必要があります。

System.out.flush()

これらのストリームに書き込まれた関連データのすべてのチャンクの後にこれを行う必要があります。すべての行の印刷後に行ってみてください。

于 2012-07-20T11:41:24.183 に答える