자바에서 파일 변환기를위한 약간의 GUI를 프로그래밍 중입니다. 파일 변환기는 현재 진행률을 stdout에 씁니다. 다음과 같습니다다른 프로세스 읽기 '** unbuffered ** 출력 스트림
Flow_1.wav: 28% complete, ratio=0,447
내가 진행률 표시 줄이를 설명하고 싶었다, 그래서 나는이 같은 표준 출력 과정 '읽고 있어요 :
ProcessBuilder builder = new ProcessBuilder("...");
builder.redirectErrorStream(true);
Process proc = builder.start();
InputStream stream = proc.getInputStream();
byte[] b = new byte[32];
int length;
while (true) {
length = stream.read(b);
if (length < 0) break;
// processing data
}
이제 문제를 관계없이 바이트 그 배열 크기를 선택하면 스트림이 4KB 청크로 읽혀집니다. 그래서 내 코드는 length = stream.read(b);
까지 실행되고 나서 꽤 오랫동안 블록됩니다. 프로세스가 4KB의 출력 데이터를 생성하면 내 프로그램은이 청크를 가져 와서 32 바이트 슬라이스로 처리합니다. 그리고 나서 다시 다음 4KB를 기다립니다.
BufferedInputStream stream = new BufferedInputStream(proc.getInputStream(), 32);
또는이 :
나는이 같은 작은 버퍼를 사용하기 위해 자바를 강제로 시도
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()), 32);
을하지만도 아무것도 변경되었습니다.
은 그 때 나는 발견이 : 그것은 Process 클래스는 파이프 프로세스가 '파일에 표준 출력 방식으로 구현되는 것 같다 Process source(라인 87의 주위에). 그래서 proc.getInputStream();
이 실제로하는 일은 스트림을 파일로 반환하는 것입니다. 그리고이 파일은 4KB 버퍼로 작성된 것 같습니다.
누군가 이러한 상황에 대한 대안을 알고 있습니까? 나는 그 과정의 결과를 즉시 얻고 싶다.
편집은 : 이안 로버츠에 의해 제안이 스트림은 BufferedInputStream
에 싸여 것 같지 않기 때문에, 나는 또한, 파이프로 표준 에러 스트림에 컨버터의 출력을 시도했다. 여전히 4k 덩어리.
또 다른 흥미로운 사실은 : 실제로 정확히 4096 바이트를 얻지는 못했지만 약 5 개 더 많습니다. FileInputStream
자체가 원래 버퍼링 된 것 같습니다. 이 과정의 표준 출력 스트림에 연결된 코드를 보면
문제가 변경되지는 않지만 Java는 데이터를 파일로 스트리밍하지 않습니다.파일 디스크립터는 운영 체제가 프로세스 입력/출력 스트림을 설명하는 방법입니다. _real_ 파일과 반드시 상관 관계가있는 것은 아닙니다. – jtahlborn
보통 stdout은이 프로세스를 쓰는 프로세스에 의해 이미 버퍼링되어 있기 때문에 다른 프로세스를 변경할 수없는 경우에는 아무런 기회가 없습니다. 이 프로세스는 버퍼링을 해제하거나 flush()를 더 자주 호출해야합니다. –
@PhilippWendler : 컨버터의 표준 출력은 4KB (터미널에서 실행할 때)보다 더 자주 플러시됩니다. stdout이 콘솔로 보내지지 않을 때 \ n의 자동 플러시가 꺼져 있다고 생각합니까? –