2012-10-31 2 views
0

Java에서 외부 프로세스를 생성하고 주기적으로 입력에 쓰고 응답을 콘솔처럼 읽을 수 있기를 바랍니다. 그러나 대부분의 경우 프로세스의 출력을 읽을 때 사용할 수있는 것이 없습니다. 이런 종류의 일을 수행하는 좋은 습관이 있습니까 (심지어 피하는 것)? 나는 내가 (다른 일부 프로세스 (고양이)에서 읽을 수는 없지만, BufferedWriter의에서의 OutputStream을 마무리하면, 이상하게도Java에서 실행중인 외부 프로세스를 안전하게 읽고 쓰는 방법은 무엇입니까?

import org.apache.commons.exec.*; 
import java.io.*; 
//... 
CommandLine cl = CommandLine.parse("/usr/bin/awk {print($1-1)}"); 
System.out.println(cl.toStrings()); 
Process proc = new ProcessBuilder(cl.toStrings()).start(); 
OutputStream os = proc.getOutputStream(); // avoiding *Buffered* classes 
InputStream is = proc.getInputStream(); // to lessen buffering complications 
os.write(("4" + System.getProperty("line.separator")).getBytes()); 
os.flush(); // Doesn't seem to flush. 
// os.close(); // uncommenting works, but I'd like to keep the process running 
System.out.println("reading"); 
System.out.println(is.read()); // read even one byte? usually is.available() -> 0 

: 여기

이 작동하지 않습니다 무엇을 벗었 예제 awk, grep).

+0

검사, http://stackoverflow.com/questions/13008526/runtime-getruntime-execcmd-hanging/13008847#13008847 여기 Arham을 – Arham

+0

감사 대답의 나. stdErr가 채워지거나 동기화 문제를 제거하는 것이 좋은 방법이라고 생각하지 않았습니다. 별도의 스레드에서 stdErr을 읽는 것이 여기에서 도움이되지는 않습니다. 프로세스에 데이터를 전달하고 프로세스가 작동하도록하고 싶습니다. 예를 들어, 셸에서 실행하는 것처럼 계속 진행하기 전에 선을 처리하거나 응답을 기다리는 등의 작업을 수행 할 수 있습니다. 그냥 외부 프로세스를 bash -c "..."로 마무리해야합니까? – jlb

+0

나는 유닉스 프로세스를 실행시키지 않았지만 자바에서 윈도우 프로세스를 시도했지만, 그걸 시험해 봐야 할 것이다. 그러나 내가 이해하는 한, 시스템이 아닌 사용자가 직접 응용 프로그램의 종료를 제어하려고합니다. 이를 위해 항상 사용자 정의 된 조건 내에 proc.destroy()를 넣을 수 있습니다. ?? – Arham

답변

1

일반적으로 취해진 접근법이 적절합니다. 그래도 몇 가지 :

  1. InputStream.read()은 차단 방법입니다. 그것은 입력을 기다리고 CPU를 많이 사용하지 않습니다. 당신은 BufferedInputStream을이 액세스 (readLine() 방법을) 완화에 스트림 단지 read(byte[] buffer, int offset, int len)
  2. 포장 입력을 사용, 한 바이트를 읽을 수있는 것보다
  3. 더 많이 ... 주위 회전한다. 이것은 BufferedReader의 대안입니다.
  4. Process.waitFor()을 반드시 사용하십시오.

또한 외부 프로세스가 표준 출력이 아닌 표준 출력에 쓰는지 확인하십시오. 여기에 두 가지 가능성 : (다른의 InputStream로 및 취급)

  1. 사용 Process.getErrorStream()/usr/bin/awk {print($1-1)} 2>&1
  2. 변경 명령 ​​행. 그러면 표준 오류가 표준 출력으로 리디렉션됩니다. 도움이된다면
+0

고마워요, user999441. Process.waitFor()는 외부 프로세스가 완료 될 때까지 차단합니다. 프로세스를 계속 실행하고 종료하기 전에 출력에서 ​​읽는 것이 좋습니다. – jlb

+0

문자 그대로 죽이거나 EOF (Ctrl + D)를 보내서 죽일 때까지 프로세스가 끝나지 않습니다. 또는 Ctrl + C를 누르십시오. 또한 파일을 입력 및 출력으로 실행하는 것이 더 좋은 아이디어 일 수 있습니다. 프로세스는 파일에 입력을하고, 작업을 수행하고, 파일에 기록하고, 완료 한 다음 Java가 출력 파일을 처리합니다. –

관련 문제