java执行命令_Java 执行系统命令

在Java中执行系统命令,主要是使用ProcessBuilder和Runtime.getRuntime().exec()。而在这里主要是介绍两种方法的使用。

使用情景是在linux系统中,使用mencoder来进行视频转码。将视频转为flv格式,因为转为flv格式命令较为简单,如要转为MP4格式,可以看官方文档介绍

一.使用Runtime

##上传之后的视频文件名为test.tmpmedia

String command = "mencoder test.tmpmedia -o test.flv -ofps 25 -of lavf -oac mp3lame -srate 22050 -ovc lavc -lavcopts "

+ "vcodec=flv:keyint=59:vbitrate=6000:mbd=2:trell:v4mv:o=mpv_flagg=cbp_rd:last_pred=3 -vf harddup,scale=480:256";

Process p = Runtime.getRuntime().exec(command);

##读取命令的输出信息

InputStream is = p.getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

p.waitFor();

if (p.exitValue() != 0) {

//说明命令执行失败

//可以进入到错误处理步骤中

}

##打印输出信息

String s = null;

while ((s = reader.readLine()) != null) {

System.out.println(s);

}

其中waitFor()方法会阻塞当前进程,直到命令执行结束。而exitValue不会阻塞进程,但是调用exitValue的时候,如果命令没有执行完成就会报错,感觉这样设计挺奇怪的。

所以,想要获取到命令是否执行成功,就搭配waitFor和exitValue。

使用Runtime执行命令感觉是比较方便的,直接可以将命令写入exec()中。如果仅仅是这样写的话,转码是会一直卡死在那里的。而你将命令直接放到终端中执行,又不会出现问题。

原因就在转码时候,会输出大量的信息(标准输出和标准错误),如果不清理java的缓存区,就会导致缓存区满而命令无法继续执行的情况。

那么解决办法肯定就是清理缓存区,而使用Runtime清理的话,你至少得再开另外一个线程,才能同时getInputStream和getErrorStream,这样并不是我喜欢的,所以便采用了ProcessBuilder

二.使用ProcessBuilder

#将命令分解为List存储

String[] commandSplit = command.split(" ");

List lcommand = new ArrayList();

for (int i = 0; i < commandSplit.length; i++) {

lcommand.add(commandSplit[i]);

}

ProcessBuilder processBuilder = new ProcessBuilder(lcommand);

processBuilder.redirectErrorStream(true);

Process p = processBuilder.start();

InputStream is = p.getInputStream();

BufferedReader bs = new BufferedReader(new InputStreamReader(is));

p.waitFor();

if (p.exitValue() != 0) {

//说明命令执行失败

//可以进入到错误处理步骤中

}

String line = null;

while ((line = bs.readLine()) != null) {

System.out.println(line);

resultLog += line;

}

ProcessBuilder可以使用redirectErrorStream将标准输出和标准错误流合并,然后使用getInputStream获取到流,放入BufferedReader中打印出来,便可解决缓存区满的问题

唯一感觉不太方便就是命令执行已List或者String []的形式传入。

上面的两种方法都是以阻塞的方式执行命令的,要想在后台执行命令,并且命令执行成功后通知,失败后记录日志,那就只能在主线程中开一个线程,专门用来转码。可以参考下一篇文章《

Spring中多线程转码,bean的注入问题》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值