2010-08-12 2 views
0

내 프로그램 중간에 배치 파일 (다른 Java 응용 프로그램을 시작합니다)을 실행하고 싶습니다. 나는 그것이 성공적으로 실행되었는지 또는 그 배치 파일을 실행하는 데서 erros를 포착하고 싶었는지 기다리고 싶지 않습니다. 그 배치 파일을 시작한 후에, 나는 그 배치를 실행 한 후에 그것을 기다리기보다는 다른 일을하고 싶다.Process.exec 사용

stdout과 stderr을 처리해야합니까? stdout과 stderr을 돌볼 수있는 방법이 있습니까?

이 항목에 대한 혼란을 없애기위한 두 번째 게시물이므로 질문에 구체적으로 답해 주시고 process.exe 또는 processbuilder를 실행하는 방법에 대한 링크를 에 보내주십시오.

도움을 주시면 감사하겠습니다.

+0

첫 번째 게시물로 연결하십시오. 참조하는 API에 대한 링크도 제공 할 수 있습니까? 지금 사용하려는 모든 예제 또는 평가판 코드가 있습니까? – Freiheit

답변

0

당신 만이 필요 생각 :

Runtime run = Runtime.getRuntime(); 
Process p = null; 
String cmd = "D:\\a.bat";  
try {  
    p = run.exec(cmd); 
}catch(Exception e){ 
    //do handling 
} 

// 코드

나중에 코드에서) (p.destroy를 호출해야합니다. 위의 코드를 별도의 스레드로 생성 할 수도 있습니다. 희망이 도움이됩니다.

+0

+1 - @ user234194 YoK의 코드를 새 클래스의 Main 메서드에 붙여 넣고 시도해보십시오. 혼란을 해결하는 가장 좋은 방법입니다. –

+0

@Andrzej Doyle 답변을 변경했습니다. – YoK

+0

좋아요, 지금은 치명적이지는 않지만 여전히 올바르지 않습니다. 질문은 근본적으로 "나는 stdout과 stderr를 돌봐야합니까?" 귀하의 대답은 ** 아니오 **를 의미합니다. 정답은 ** 예 **입니다. –

0

프로세스가 stdout 또는 stderror로 출력을 생성하지 않으면 처리 할 필요가 없을 것입니다. 당신의 서브 프로세스가 출력을 생산한다면 블록을 영원히 stdout에 쓰려고 시도하는 동안 OS 파이프가 얼마만큼 버퍼링 하는가에 달려있다. 모든 사람들이 사용하는 스트림 플러시 어딘가에 여기에 예제가 있습니다.

2

나는 적어도 stdout과 stderr를 먹지 않으면 결국 메모리가 부족하다는 것을 발견했다. 그것은 또한 하나 이상의 Process을 동시에 돌릴 수 없었습니다.

저는 이것을 처리하기 위해 ProcessStreamEater라는 클래스를 사용하고 있습니다. 그런 다음

public class ProcessStreamEater implements Runnable 
{ 
    private final Process proc; 

    public ProcessStreamEater(Process proc) 
    { 
     this.proc = proc; 
    } 

    @Override 
    public void run() 
    { 
     InputStreamReader r = new InputStreamReader(proc.getInputStream()); 
     try 
     { 
     while(r.read() != -1) 
     { // put stuff here if you want to do something with output 
      // otherwise, empty 
     } 
     } 
     catch(IOException e) 
     { 
     // handle IO exception 
     } 
     finally 
     { 
     if(r != null) 
     { 
      try 
      { 
       r.close(); 
      } 
      catch(IOException c) 
      {} 
     } 
     } 
    } 
} 

내가 물건을 먹고 그것을 사용 ... ExecutorService를가 Executors.newCachedThreadPool()

+0

'proc.getErrorStream()'을 잊지 마라! 그렇지 않으면, 내가이 상황에서 조언하고자하는 것과 매우 유사합니다. –

+0

그래서 리디렉션 오류 스트림을 호출합니다. 그들은 둘 다 stdout로갑니다. –

3

짧은 대답하여 만든

ProcessBuilder pb = new ProcessBuilder(args); 
    pb.redirectErrorStream(true); 
    final Process proc = pb.start(); 
    executorService.execute(new ProcessStreamEater(proc)); 

: 번호를 프로세스 'javadocs 당으로,

일부 기본 플랫폼은 표준 입력 및 출력 스트림에 대해 제한된 버퍼 크기만을 제공하기 때문에 fai 즉각적으로 입력 스트림을 작성하거나 하위 프로세스의 출력 스트림을 읽으면 하위 프로세스가 블록화되고 심지어 교착 상태가 발생할 수 있습니다.

프로그램을 원격으로 강력하게하려면 stderr 및 stdout 처리를 처리해야합니다.

정말로의 내용에 대해서는 신경 쓰지 않아도됩니다. (좋은 생각이 아닙니다. 배치가 유용한 오류 메시지와 함께 실패하면 어떻게됩니까?) Jay R.'s answer에 따라 읽습니다. 이렇게하면 스트림 상태에 대해 걱정하지 않고 논리 스레드를 계속 진행할 수 있으며 스트림이 고갈 될 때까지 스트림 도우미가 백그라운드에서 실행됩니다.Runtime.exec() 주위의 래퍼를 만들어서 스레드를 실행하여이 작업을 많이 수행 할 수도 있습니다.

그러나 코드에서 intepret을 수행하지 않을 경우 적어도 로그 일괄 처리의 결과가 출력됩니다. 일괄 처리에 문제가 생길 때 문제를 분석하는 것이 프로세스의 결과물을 훨씬 쉽게 처리 할 수 ​​있습니다.

+0

나는 당신이 설명하려고하는 것을 이해한다고 생각합니다. 일괄 처리에서 실행하려고하는 다른 프로그램이 모든 로그를 유지하고 처리하는 것을 지우면 어떻게 될까요? 그리고 하나 이상의 질문이 있습니다. 여러 배치 파일을 실행해야하는 경우 각각 다른 하나를 완료하고 처리하기를 기다릴 필요가 있습니까? 또 다른 하나가 완료되면 다른 하나가 다시 시작될 때까지 기다려야합니까? – user234194

+0

나는 너의 대답을 좋아한다. :) –

+0

@ user213194 - 여러 배치 파일을 실행하려면 한 번에 모든 프로세스에서 읽을 충분한 스레드를 만드는 한 Java에서 동시에 실행할 수 있습니다. (이것은 배치 파일이 서로 간섭하지 않고 실행될 수 있다고 가정합니다. 물론 Java 또는 '프로세스'와 관련이 없습니다.) –