Demo
涉及到执行外部函数时的环境变量
使用LineNumberReader处理执行结果
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.dahuazwan.backup.pojo.BackupPojo;
public class Backup {
private static Log log = LogFactory.getLog(Backup.class);
/**
*
* @param backupPojo
* @param iAllback true:备份全部;否则备份指定表
*/
public void execute(BackupPojo backupPojo,boolean iAllback){
ProcessBuilder pb = new ProcessBuilder("cmd","/c",backupPojo.toBackupSql(iAllback));
// 设置环境变量
Map<String, String> env = pb.environment();
// 设置新的环境变量
String sMysqlbindir = backupPojo.getsMysqlbindir();
if(sMysqlbindir != null && !"".equals(sMysqlbindir)){
this.changeEnv(env, "path", backupPojo.getsMysqlbindir(), false);
}
// // 打印
// Iterator<String> it = env.keySet().iterator();
// while(it.hasNext()){
// String key = it.next();
// System.out.println(key + " = " + env.get(key));
//
// }
Iterator<String> it = env.keySet().iterator();
while(it.hasNext()){
String key = it.next();
System.out.println(key + " = " + env.get(key));
}
// pb.directory();
try {
Process p = pb.start();
//打印错误流信息
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(p.getErrorStream()));
String s;
while( (s = lnr.readLine()) != null){
// 打印错误信息
log.error(s);
}
// 如果行号为0,则无错误信息,执行命令成功,否则失败
if(lnr.getLineNumber() == 0){
log.info(" back up database ok !");
}else{
log.info(" back up database failure ! cmd = \" " + backupPojo.toBackupSql(iAllback) + "\"") ;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.info(" back up database failure ! cmd = \" " + backupPojo.toBackupSql(iAllback) + "\"") ;
log.error(e);
}
}
/**
*
* @param sName 非空
* @param sValue
* @param isAppend true:append:false:替换
*/
public void changeEnv(Map<String, String> env,String sName,String sValue, boolean isAppend ){
// 全部小写
Iterator<String> it = env.keySet().iterator();
while(it.hasNext()){
String sKey = it.next();
if(sName.equalsIgnoreCase(sKey)){
if(isAppend){
// append
String sT = env.get(sKey);
if(sT == null || "".equals(sT)){
sT = sValue;
}else{
sT = sT + ";" + sValue;
}
env.put(sKey, sT);
}else{
//替换
env.put(sKey, sValue);
}
}
}
}
}
Demo 2:
比第一个好:
public class DosRun {
private static Log log = LogFactory.getLog(DosRun.class);
/**
* 执行外部程序,此程序无输入流
* @param sCommand
*/
public static void execute(List<String> lCommand){
try{
if(log.isInfoEnabled()){
log.info("Command = " + lCommand);
}
ProcessBuilder pb = new ProcessBuilder(lCommand);
pb.redirectErrorStream(true); //错误和正确信息合并输出
Process p = pb.start();
p.getOutputStream().close(); //关不输出
// 打印处理消息
String sInfo = readInputStream(p.getInputStream());
log.info("Info = " + sInfo);
int iResult = p.exitValue();
if(iResult == 0){
log.info(" result = " +p.exitValue() + "execute command success! Command = " + lCommand);
}else{
log.info(" result = " +p.exitValue() + "execute command failure! Command = " + lCommand);
}
}catch(Exception e){
throw new RuntimeException(e);
}
}
/**
* 执行程序,该程序由输入流
* @param lCommand
* @param sFile 成员要接收的数据文件
*/
public static void execute(List<String> lCommand, String sFile){
try{
if(log.isInfoEnabled()){
log.info("Command = " + lCommand);
}
ProcessBuilder pb = new ProcessBuilder(lCommand);
pb.redirectErrorStream(true); //错误和正确信息合并输出
Process p = pb.start();
FileInputStream fis = new FileInputStream(sFile);
OutputStream os = p.getOutputStream();
byte[] b = new byte[8192];
int num = 0;
while((num = fis.read(b) )!= -1){
os.write(b,0,num);
}
os.close();
// 打印处理消息
String sInfo = readInputStream(p.getInputStream());
log.info("Info = " + sInfo);
int iResult = p.exitValue();
if(iResult == 0){
log.info(" result = " +p.exitValue() + "execute command success! Command = " + lCommand);
}else{
log.info(" result = " +p.exitValue() + "execute command failure! Command = " + lCommand);
}
}catch(Exception e){
throw new RuntimeException(e);
}
}
/**
* 读取流中数据,并返回给用户
* @return
* @throws IOException
*/
private static String readInputStream(InputStream in) throws IOException{
StringBuilder sb = new StringBuilder();
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(in));
String s;
while( (s = lnr.readLine()) != null){
// 打印信息
System.out.println(s);
sb.append(s).append("\r\n");
}
return sb.toString();
}
}
参考文献
- [java调用外部可执行程序] 2. java输入输出重定向 取得Runtime.getRuntime().exec("cmd /c dir")的输入输出; 利用ProcessBuilder来创建Process对象,执行外部可执行程序;如何协调外部进程与当前Java进程(waitFor方法和执行DOS的内部命令)
- Java调用外部程序命令 阅读ProcessBuilder源代码后对List参数的空格处理说明;将标准输出和错误输出合并,一起读出来或者在另外的线程中读出来;如果不使用标准输入,建议close
- 使用ProcessBuilder执行本地命令 Demo