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 中有多 ...
随机推荐
- 利用git+hugo+markdown 搭建一个静态网站
利用git+hugo+markdown 搭建一个静态网站 一直想要有一个自己的文档管理系统: 可以很方便书写,而且相应的文档很容易被分享 很方便的存储.管理.历史记录 比较方面的浏览和查询 第一点用M ...
- Spring Batch学习笔记三:JobRepository
此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch Job在运行时有很多元数据,这些元数据一般会被保存在内存或者数据库中,由于Spring Batch在默认配置是使用H ...
- C# 获取当前路径方法
//获取包含清单的已加载文件的路径或 UNC 位置. public static string sApplicationPath = Assembly.GetExecutingAssembly ( ) ...
- AOP报错:Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut
Spring3.x升级4.x时遇到的,JDK版本1.7 aspectj版本问题,1.6.x升级到1.7.x,解决!
- mongoose 的 model,query:增删改查
简介 mongoose是node.js的一个操作mongodb的模块,比起之前mongodb模块,只需要在开始时连接,不需要手动关闭,十分方便. 连接mongodb 首先你需要安装mongodb.有了 ...
- lua 和 c/c++ 交互 (持续更新)
参考: http://blog.csdn.net/xiaohuh421/article/details/7476485 http://blog.csdn.net/shun_fzll/article/d ...
- Android开发工具类
7种无须编程的DIY开发工具 你知道几个? 现如今,各种DIY开发工具不断的出现,使得企业和个人在短短几分钟内就能完成应用的创建和发布,大大节省了在时间和资金上的投入.此外,DIY工 具的出现,也帮助 ...
- Mybatis架构学习
Mybatis架构学习 MyBatis 是支持定制化 SQL.存储过程以及高级映射的持久层框架.MyBatis 封装了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.可以对配置和原生Map使用 ...
- ubuntu各种应用安装
微信安装,编译包下载,双击electronic-wechat就能用了,记得lock在launcher上 https://github.com/geeeeeeeeek/electronic-wechat ...
- AS 重装系统之后配置
重新安装了win7 系统,一起的AS 放在其他盘里 1.重新安装java sdk 配置java 环境. 2,从新配置AS 工作界面及各种配置 3,重新安装genymotion 并在as 中配置 出现 ...