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<String> lcommand = new ArrayList<String>();
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>
或者String []
的形式传入。
上面的两种方法都是以阻塞的方式执行命令的,要想在后台执行命令,并且命令执行成功后通知,失败后记录日志,那就只能在主线程中开一个线程,专门用来转码。可以参考下一篇文章《
Spring中多线程转码,bean的注入问题》
Java 执行系统命令的更多相关文章
- Java 执行系统命令工具类(commons-exec)
依赖jar <!-- 可以在JVM中可靠地执行外部进程的库. --> <dependency> <groupId>org.apache.commons</gr ...
- Java执行系统命令工具类(JDK自带功能)
CommandUtil.java package utils; import java.io.ByteArrayOutputStream; import java.io.IOException; im ...
- java执行系统命令, 返回执行结果
package com.geostar.gfstack.opinion.util; import java.io.BufferedReader; import java.io.Closeable; i ...
- java中执行系统命令
java程序中执行系统命令猛击下面的链接看看你就知道怎么用了 http://blog.csdn.net/a19881029/article/details/8063758 http://wuhongy ...
- 在Loadrunner中如何用system函数执行系统命令
前提: windows 系统 实现功能:用 LR 中的system函数执行系统命令 相关功能:在LR中利用C函数建立文件,写文件,读文件. 主要相关函数:sprintf/fopen/fgetc/fre ...
- Oracle数据库提权(dba权限执行系统命令)
0x01 提权准备 这里我们先创建一个低权限的用户test SQL> conn sys/admin123@orcl as sysdba; 已连接. SQL> create user tes ...
- java 执行shell命令及日志收集避坑指南
有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...
- Java执行Dos-Shell脚本
Java执行Dos-Shell脚本 1.介绍 2.调用shell脚本 2.1 获取键盘输入 2.2 构建指令 2.3 Java代码 3.Java调用Shell并传入参数 4.Java调用远程的Shel ...
- java 执行 jar 包中的 main 方法
java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...
随机推荐
- URL跳转的几种方式
1.HTML: ①. <head> <!-- 以下方式只是刷新不跳转到其他页面 --> <meta http-equiv="refresh" cont ...
- 【转】lower_case_table_names=1 让MySQL不区分大小写
lower_case_table_names=1 让MySQL不区分大小写! 此前有款网络游戏的数据库是采用MySQL.操作系统是CentOS.部分服务器的操作系统又是Windows. 出现了一个小毛 ...
- s5pv210编译qt
undefined reference to `rpl_malloc' 编译tslib,执行make时提示undefined reference to `rpl_malloc' 是因为config.h ...
- css3动画之小牛奔跑
今天突然看到阿里云官网的一个悬浮效果挺炫的,就想知道到底是怎么做的,研究了半天,加了一个技术群,原来是css3做的,然后做了一个小 Demo记录下来: <!DOCTYPE html> &l ...
- 《写给大忙人看的java se 8》笔记
现在才来了解java8,是不是后知后觉了点? 新的编程技术,个人不喜欢第一时间跟进. 待社区已有实践积淀再切入似乎更划算些? 一点点精明的考虑. 不多说,上代码. //读<写给大忙人看的java ...
- 不可错过的炒鸡棒的js迷你库
小而美被实践是最好用的,这里收藏了一些很好用的js库,他们都功能单一且非常小. COOKIE.JS https://github.com/js-coder/cookie.js 如果你操作过cooki ...
- jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
jQuery(function ($) { // 备份jquery的ajax方法 var _ajax = $.ajax; // 重写ajax方法,先判断登录在执行succes ...
- ThreadLocal是什么?保证线程安全
早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使 ...
- Promise对象
1.Promise思想:每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程.这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用. ...
- 深入分析ClassLoader
首先介绍下ClassLoader: ClassLoader顾名思义就是类加载器,负责将Class加载到JVM中,事实上ClassLoader除了能将Class加载到JVM中之外,还有一个重要的作用就是 ...