2

プログラムの問題はリアルタイムで動作します。
例: getevent
しかし、プロセスから出てくるデータを読み込もうとすると、exec はそれらの部分に少なくとも 4096 バイトを与えます!

例えば:

  • getevent が1000 バイトのテキストを 返した場合: stdout.available () == 0
  • getevent が4000 バイトのテキストを 返した場合: stdout.available () == 0
  • getevent が 4096 バイトのテキストを返した場合: stdout.available () == 4096
  • getevent が 8192 バイトのテキストを返した場合: stdout.available () == 8192
  • getevent が10000 バイトのテキストを 返した場合: stdout.available () == 8192

stdout.read() を使用する場合、関数は 4096*n バイトまで、または getevent が閉じられるまで待機します。

4096 バイトがダイヤルされるまで待つのではなく、リアルタイムでデータを読み取るにはどうすればよいですか?

Process p = Runtime.getRuntime().exec(new String[]{"su", "-c", "system/bin/sh"});
DataOutputStream stdin = new DataOutputStream(p.getOutputStream());
stdin.writeBytes("getevent\n");
InputStream stdout = p.getInputStream();
byte[] buffer = new byte[1];
int read;
String out = new String();
while(true){
  read = stdout.read(buffer);
  out += new String(buffer, 0, read);
  System.out.println("MYLOG: "+(new String(buffer, 0, read)));
}

これはドキュメントでバフされていることがわかりました!

ストリームの最後に到達するまで、InputStream を OutputStream にコピーします。このメソッドは、4096 kbyte のバッファを使用します。

>>ドキュメント

4

1 に答える 1

1

この原因として最も可能性が高いのは、外部アプリケーションがその出力をバッファリングしていることです。これは、「標準出力」に書き込んでいるアプリケーションでは非常に一般的です。解決策は、適切なタイミングで出力を「フラッシュ」するように外部アプリケーションを変更することです。

読み取り可能なデータがある場合、Java コードに遅延を引き起こすものは何もありません。特に、DataOutputStream を使用しても、これは発生しません。


available()信頼できる情報を提供しないことにも注意する必要があります。API ドキュメントを注意深く読むと、戻り値Nonly は、同時に N バイトを超える読み取りを試みるとブロックされる可能性があることを意味することがわかります。available()スレッドは両方をread()同時に呼び出すことはできないため、スレッドによって提供される情報を使用するようになるまでには、available()古くなる可能性があります。

于 2013-03-10T00:57:25.333 に答える