在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的时候,如果命令没有执行完成就会报错,感觉这样设计挺奇怪的。

所以,想要获取到命令是否执行成功,就搭配waitForexitValue

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

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

那么解决办法肯定就是清理缓存区,而使用Runtime清理的话,你至少得再开另外一个线程,才能同时getInputStreamgetErrorStream,这样并不是我喜欢的,所以便采用了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 执行系统命令的更多相关文章

  1. Java 执行系统命令工具类(commons-exec)

    依赖jar <!-- 可以在JVM中可靠地执行外部进程的库. --> <dependency> <groupId>org.apache.commons</gr ...

  2. Java执行系统命令工具类(JDK自带功能)

    CommandUtil.java package utils; import java.io.ByteArrayOutputStream; import java.io.IOException; im ...

  3. java执行系统命令, 返回执行结果

    package com.geostar.gfstack.opinion.util; import java.io.BufferedReader; import java.io.Closeable; i ...

  4. java中执行系统命令

    java程序中执行系统命令猛击下面的链接看看你就知道怎么用了 http://blog.csdn.net/a19881029/article/details/8063758 http://wuhongy ...

  5. 在Loadrunner中如何用system函数执行系统命令

    前提: windows 系统 实现功能:用 LR 中的system函数执行系统命令 相关功能:在LR中利用C函数建立文件,写文件,读文件. 主要相关函数:sprintf/fopen/fgetc/fre ...

  6. Oracle数据库提权(dba权限执行系统命令)

    0x01 提权准备 这里我们先创建一个低权限的用户test SQL> conn sys/admin123@orcl as sysdba; 已连接. SQL> create user tes ...

  7. java 执行shell命令及日志收集避坑指南

    有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...

  8. Java执行Dos-Shell脚本

    Java执行Dos-Shell脚本 1.介绍 2.调用shell脚本 2.1 获取键盘输入 2.2 构建指令 2.3 Java代码 3.Java调用Shell并传入参数 4.Java调用远程的Shel ...

  9. java 执行 jar 包中的 main 方法

    java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...

随机推荐

  1. 初次了解的Java多线程

    0.1熟悉多线程 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能 ...

  2. python之信用卡ATM(第五天)

    本节作业 作业需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日, ...

  3. JSON.stringify()

    概述 JSON.stringify() 方法可以将任意的 JavaScript 值序列化成 JSON 字符串. 语法 JSON.stringify(value[, replacer [, space] ...

  4. Swift语言之命令模式(Command Pattern)实现

    今天遇到这样一个问题,我现在有一个整数数组,如: var numbers = [3, 7, 12, 9, 200] 现需要对其中的每一个数字都执行一系列相同的加减乘除操作,如对每一个数字都加5乘8再减 ...

  5. PHP命令行脚本接收传入参数的三种方式

    通常PHP都做http方式请求了,可以使用GET or POST方式接收参数,有些时候需要在shell命令下把PHP当作脚本执行,比如定时任务.这就涉及到在shell命令下如何给php传参的问题,通常 ...

  6. ubuntu14.04设置静态ip

    1. 找到文件并作如下修改: sudo vim /etc/network/interfaces 修改如下部分: auto eth0 iface eth0 inet static address 192 ...

  7. CSS使用

    CSS介绍 css是英文Cascading Style Sheets的缩写,称为层叠样式表,用于对页面进行美化. 语法:style = 'key1:value1;key2:value2;' 存在方式有 ...

  8. MVC JS中非表单元素路由传值

    <span id="a" onclick="aaa(111)" style="cursor:pointer;">跳</sp ...

  9. Android Gallery

    xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...

  10. (转)sqlplus中文显示乱码的问题

    sqlplus中文显示乱码的问题 2010-07-19 11:33:26 分类: LINUX 在windows下sqlplus完全正常,可是到linux下,sqlplus中文显示就出问题了,总是显示“ ...