2013-03-09 3 views
2

프로그램의 문제점은 실시간으로 작동합니다.
예 : getevent
그러나 프로세스에서 나오는 데이터를 읽으려고하면 exec는 최소한 4096 바이트를 제공합니다!Runtime.getRuntime()의 실시간 읽기 exec()

  • getevent 반환 경우 1000 바이트의 텍스트 : getevent의 텍스트 4000 바이트 반환 0
  • 경우 stdout.available() == 표준 출력 예

    .available() == 0

  • getevent가 4096 바이트의 텍스트를 반환하면 : stdout.available() == 4096
  • getevent 텍스트의 8192 바이트를 반환하는 경우 10
  • 그 : 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))); 
} 

나는 이것을 문서에서 발견했습니다! 스트림이 끝날 때까지의 OutputStream에

가 복사되는 InputStream은 도달되었다. 이 방법은 4096k 바이트의 버퍼를 사용합니다.

>>Documentation

+0

[프로세스]에 대한 javadoc (http://developer.android.com/reference/java/lang/Process.html)은 1) 프로세스의'stdout'과'stderr' 스트림을 두 개의 쓰레드에서 동시에 읽거나 2) [redirectErrorStream (true)'] (http://developer.android.com/reference/java /lang/ProcessBuilder.html#redirectErrorStream(boolean))를 사용하여 스트림을 병합합니다. 만약 당신이 그 중 하나를하지 않으면 그 과정은 막을 수있다 :''이 스트림들이 읽히지 않으면, 버퍼 공간을 기다리는 동안 대상 프로세스가 차단 될 수있다. '''stderr'를 무시하면 실시간으로'stdout'를 읽지 못할 것입니다 ? 코드에서 – user113215

+0

는'stdout'은 [항상 '0'반환]하는'InputStream' (http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#이다 available())에서'available()'메소드를 호출한다. 또한 연결된 클래스는 공식적인 것이 아니며 4KB의 버퍼를 사용합니다. 1B의 버퍼를 사용합니다. –

+0

@ user113215 선택됨. 도와주지 않았어. 4096 * n bytes ... – MixerOID

답변

1

이것의 원인은 외부 프로그램의 출력을 버퍼링하는 것이있다. 이는 "표준 출력"에 쓰는 응용 프로그램에서 매우 일반적입니다. 해결 방법은 적절한 시간에 출력을 "플러시"하도록 외부 응용 프로그램을 수정하는 것입니다.

읽을 수있는 데이터가있는 경우 지연을 유발하는 Java 코드는 없습니다. 특히, DataOutputStream의 사용은 이것을 발생시키지 않습니다.


available()은 신뢰할 수있는 정보를 제공하지 않는다는 점에 유의해야합니다. API 문서를주의 깊게 읽으면 반환 값 N은 N 바이트 이상을 읽는 동시 시도가 일 수 있으며 블록 일 수 있음을 나타냅니다. 스레드는 available()read()을 동시에 호출 할 수 없으므로 available()에서 제공된 정보를 사용하기 전에는 스레드가 오래되었을 수 있습니다.

+0

'외부 응용 프로그램이 output.' 터미널 에뮬레이터가 잘 작동 버퍼링되는이의 가장 큰 원인은 ...'자바 코드에 아무것도 없다 ...'[링크 1] (HTTP : //www.java2s .COM/코드/자바/파일 입력 - 출력/CopiestheInputStreamintotheOutputStreamuntiltheendofthestreamhasbeenreachedThismethodusesabufferof4096kbyte.htm) [링크 2] (http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedInputStream.html#count) 코멘트가 없습니다 ... – MixerOID

관련 문제