首页 > 编程语言 > 详细

Java Process类小试后感

时间:2015-11-03 23:12:53      阅读:456      评论:0      收藏:0      [点我收藏+]

    前言:虽然没什么空,但是也要硬着头皮更新一下最近遇到的问题。

    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()的话会出问题的说。

Java Process类小试后感

原文:http://my.oschina.net/joshuashaw/blog/525509

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!