前言:虽然没什么空,可是也要硬着头皮更新一下最近遇到的问题。java
Java项目中须要调用到ffmpeg命令,得知Java的Process类能够使用。shell
常规的Process类使用网上有不少,贴一个最经典的例子。tomcat
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对象的输入。ide
通常来讲是相安无事的,不过当你调用长时间工做的命令时,该命令的输入流里将有大量数据写进缓冲区,若你不取出来,命令将再也不执行,而是阻塞,等待你的取出。这是代码就没法继续运行下去了。ui
当我在jdk7和tomcat6下把三个流都关闭时,shell命令是能够执行的。code
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()的话会出问题的说。部署