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