Java Runtime 기반 외부 프로그램 호출 장애 해결 방법

2802 단어 Java막다
본고는 자바가 Runtime을 바탕으로 외부 프로그램을 호출하는 데 막히는 해결 방법을 설명하는 실용적인 기교이다.여러분에게 참고할 수 있도록 나누어 드리겠습니다.구체적인 분석은 다음과 같다.
때때로 자바 코드에서 일부 외부 프로그램을 호출할 수 있다. 예를 들어 SwfTools는 swf, ffmpeg는 동영상을 변환한다.만약 당신의 코드가 이렇게 쓰인다면: Runtime.getRuntime().exec(command), 프로그램이 한 번에 실행되는 것을 발견할 수 있습니다. 명령줄에서 잠시 실행해야 합니다. 자바가 외부 프로그램의 실행을 기다리지 않았기 때문입니다. 이 때 외부 프로그램의 실행 결과를 기다리기 위해 막힘을 사용해야 합니다.

InputStream stderr = process.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr, "GBK");
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
  System.out.println(line);
int exitValue = process.waitFor();

일반적인 외부 프로그램에 대해 위의 차단 코드를 사용하면 된다. 적어도 pdf2swf.exe는 문제없습니다.
그러나 이어서 ffmpeg에 대해 상기 코드는 프로그램을 멈추게 하고 다른 방식을 사용해야 한다는 것을 발견했다. 다음과 같은 방법으로 봉인했다.

@SuppressWarnings("static-access")
public static int doWaitFor(Process process) {
  InputStream in = null;
  InputStream err = null;
  int exitValue = -1; // returned to caller when p is finished
  try {
    in = process.getInputStream();
    err = process.getErrorStream();
    boolean finished = false; // Set to true when p is finished
    while (!finished) {
      try {
        while (in.available() > 0) {
          // Print the output of our system call
          Character c = new Character((char) in.read());
          System.out.print(c);
        }
        while (err.available() > 0) {
          // Print the output of our system call
          Character c = new Character((char) err.read());
          System.out.print(c);
        }
        // Ask the process for its exitValue. If the process
        // is not finished, an IllegalThreadStateException
        // is thrown. If it is finished, we fall through and
        // the variable finished is set to true.
        exitValue = process.exitValue();
        finished = true;
      } catch (IllegalThreadStateException e) {
        // Process is not finished yet;
        // Sleep a little to save on CPU cycles
        Thread.currentThread().sleep(500);
      }
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    try {
      if (in != null) {
        in.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    if (err != null) {
      try {
        err.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  return exitValue;
}

본 논문이 여러분의 Java 프로그래밍 학습에 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기