疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java借助Runtime调用外部程序阻塞的代码


 

   

  有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf、ffmpeg来转换视频等。如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果:

  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;

  }