2012-01-05 3 views
9

ProcessBuilder에서 생성 된 하나의 프로세스 출력을 다른 ProcessBuilder에서 생성 된 다른 프로세스로 전달할 수 있습니까? 예를 들어,이 셸 명령을 실행하려고하는 경우 :ProcessBuilder에서 다른 ProcessBuilder로 파이핑 출력

ls | grep build.xml 

ProcessBuilder는 어떻게해야합니까?

Process process = Runtime.getRuntime().exec("ls"); 
InputStream is = process.getInputStream(); 
byte[] buf = new byte[1000]; 
is.read(buf); 
String parameter = new String(buf); 
System.out.println("grep build " + parameter); 

Process proc2 = Runtime.getRuntime().exec("grep build " + parameter); 
InputStream is2 = proc2.getInputStream(); 
byte[] buf2 = new byte[1000]; 
is2.read(buf2); 
String result = new String(buf2); 
System.out.println("proc2 result: " + result); 

하지만 다른 결과 내가 쉘에서 직접 스크립트를 실행할 때와 비교 생산 : @erdinc이 제안

, 나는이 시도. 나는 어디에서 잘못 했는가? 해결

는 : 같은 매개 변수 두 번째 프로세스를 전달보다 당신이는 getInputStream 방법을 사용할 수 있습니다 필립 웬 들러 솔루션

답변

6

해결 방법의 문제점은 ls의 출력에서 ​​처음 1000 바이트 만 읽고 grep에 전달한다는 것입니다. ls의 출력 양을 모르기 때문에, 출력이 완전히 소모 될 때까지 반복해서 읽어야합니다.

여기 그렙 출력의 각 행을 보내드립니다의 BufferedReader를 사용하여 솔루션입니다 : 당신은 추가해야 물론

Process lsProcess = Runtime.getRuntime().exec("ls"); 
BufferedReader lsOutput = new BufferedReader(new InputStreamReader(lsProcess.getInputStream())); 
Process grepProcess = Runtime.getRuntime().exec("grep build.xml"); 
BufferedWriter grepInput = new BufferedWriter(new OutputStreamWriter(grepProcess.getOutputStream())); 

String line; 
// read each line from ls until there are no more 
while ((line = lsOutput.readLine()) != null) { 
    // and send them to grep 
    grepInput.write(line); 
    grepInput.newLine(); 
} 

// send end-of-file signal to grep so it will terminate itself 
grepInput.close(); 

를 적절한 오류 처리 여기. 이 솔루션이 너무 느린 경우 판독기 및 작성기를 생략하고 입력 스트림에서 byte[] 배열을 입력 스트림으로 직접 전달할 수 있습니다.

그러나 더 나은 해결책은 ls 및 grep을 사용하여 파일 시스템에서 파일을 찾는 것이 아니라 적절한 Java API를 사용하는 것입니다. 예를 들어, 관심있는 디렉토리에 대해 File 오브젝트를 작성한 경우 다양한 listFiles 메소드를 사용하여이 디렉토리의 모든 파일을 나열 할 수 있습니다. 이 방법은 훨씬 쉽고 이식성이 뛰어나고 오류가 발생하기 쉽고 빠를 수도 있습니다.

+0

귀하의 솔루션이 작동합니다! 감사합니다 Philipp : D 저는 실제로이 코드를 사용하여 chasen 및 moses (기계 번역 도구)와 같은 여러 외부 응용 프로그램을 호출합니다. ls | grep 예제는 질문을 단순화하기위한 것이었지만 제안에 감사드립니다. D 해결 된 질문을 표시하고 솔루션을 upvote합니다. – ndriks

0

를 참조하십시오. 예제 코드;

+0

"ls"입력 스트림을 "grep"프로세스로 전달하는 방법은 무엇입니까? 프로세스에서 setInputStream 메서드를 찾을 수 없습니다. 또한 ProcessBuilder로 처리 할 수 ​​있습니까? – ndriks

+0

솔루션 @erdinc를 사용해 보았지만 쉘에서 직접 명령을 실행하는 것과는 다른 결과가 나옵니다. 나는 내가 한 일을 보여주기 위해 질문을 편집했다. FYI, 필자는 ls 결과를 매개 변수로 사용하여 grep을 실행하지는 않지만 ls의 결과를 grep 프로세스로 파이프하려고합니다. – ndriks

관련 문제