Java Process类小试后感

    前言:虽然没什么空,可是也要硬着头皮更新一下最近遇到的问题。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()的话会出问题的说。部署

相关文章
相关标签/搜索