前言:虽然没什么空,但是也要硬着头皮更新一下最近遇到的问题。
Java项目中需要调用到ffmpeg命令,得知Java的Process类可以使用。
常规的Process类使用网上有很多,贴一个最经典的例子。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class ExecShell { public static void main(String args[]) { Process process = null; List<String> processList = new ArrayList<String>(); try { process = Runtime.getRuntime().exec("ps -aux"); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { processList.add(line); } input.close(); try { process.waitFor(); } catch (Throwable e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } for (String line : processList) { System.out.println(line); } } }
这里Runtime类是单例,从该类调用exec(String)方法可以获得Process对象。Process对象有三个流对象,对应三个管道:标准输入流,标准输出流和错误流。标准输入流和错误流其实是Process类的输出,标准输出流则是Java代码对Process对象的输入。
一般来说是相安无事的,不过当你调用长时间工作的命令时,该命令的输入流里将有大量数据写进缓冲区,若你不取出来,命令将不再执行,而是阻塞,等待你的取出。这是代码就无法继续运行下去了。
当我在jdk7和tomcat6下把三个流都关闭时,shell命令是可以执行的。
process.getErrorStream().close(); process.getInputStream().close(); process.getOutputStream().close();
但是,当我部署到jdk8和tomcat7时,以上的代码使得shell命令不执行,所以我只能一直把输入流的数据取出来。这次,我使用ProcessBuilder类获得Process对象,把标准输入流和错误流合并,并且一直往输入流取出数据。于是长时间运行的shell命令得以运行。
@Override public String call(String shellString){ Process process = null; try { ProcessBuilder pBuilder = new ProcessBuilder(shellString.split(" ")); pBuilder.redirectErrorStream(true); process = pBuilder.start(); process.getOutputStream().close(); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { //System.out.println(line); } input.close(); System.out.println(shellString); try{ process.waitFor(); }catch(Throwable e){ e.printStackTrace(); } process.destroy(); } catch (IOException e) { e.printStackTrace(); } return " < Finished: " + shellString + " > "; }
最后建议,输入流的数据还是取出来吧,close()的话会出问题的说。
原文:http://my.oschina.net/joshuashaw/blog/525509