java调用cmd命令
1.使用Runtime中exec(String command)方法执行cmd命令,如下:
Process p = Runtime.getRuntime().exec(cmd);
此方法会抛出IOException,但是在项目中遇到没有出现异常,命令也没有执行的情况。
2.此方法可以达到大多的cmd调用的期望结果,但有些时候回出现命令卡死在p.waitFor();上,造成线程阻塞,原因:https://blog.csdn.net/weixin_34408624/article/details/86015882
public static boolean runCMD(String cmd) throws IOException, InterruptedException { final String METHOD_NAME = "runCMD"; Process p = Runtime.getRuntime().exec(cmd); BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(p.getErrorStream())); String readLine = br.readLine(); StringBuilder builder = new StringBuilder(); while (readLine != null) { readLine = br.readLine(); builder.append(readLine); } logger.debug(METHOD_NAME + "#readLine: " + builder.toString()); p.waitFor(); int i = p.exitValue(); logger.info(METHOD_NAME + "#exitValue = " + i); if (i == 0) { return true; } else { return false; } } catch (IOException e) { logger.error(METHOD_NAME + "#ErrMsg=" + e.getMessage()); e.printStackTrace(); throw e; } finally { if (br != null) { br.close(); } } }
3.使用以下方法不会出现和2一样情况下得阻塞的问题,与2的区别就是获取流不同,将getErrorStream换成getInputStream就好了
public static boolean runCMD(String cmd) throws IOException, InterruptedException { final String METHOD_NAME = "runCMD"; // Process p = Runtime.getRuntime().exec("cmd.exe /C " + cmd); Process p = Runtime.getRuntime().exec(cmd); BufferedReader br = null; try { // br = new BufferedReader(new InputStreamReader(p.getErrorStream())); br = new BufferedReader(new InputStreamReader(p.getInputStream())); String readLine = br.readLine(); StringBuilder builder = new StringBuilder(); while (readLine != null) { readLine = br.readLine(); builder.append(readLine); } logger.debug(METHOD_NAME + "#readLine: " + builder.toString()); p.waitFor(); int i = p.exitValue(); logger.info(METHOD_NAME + "#exitValue = " + i); if (i == 0) { return true; } else { return false; } } catch (IOException e) { logger.error(METHOD_NAME + "#ErrMsg=" + e.getMessage()); e.printStackTrace(); throw e; } finally { if (br != null) { br.close(); } } }
4.对于3方法有个缺点是执行错误时无法将错误消息打印出来,还有一个方法是先将执行的cmd命令写入到文件中后再执行,这是如果执行错误日志可以打印,线程也不会卡死。
a.将执行的命名写入到文件中。FileUtils.java
public static boolean writeFile(File exportFile, final String content) { if (exportFile == null || StringUtils.isEmpty(content)) { return false; } if (!exportFile.exists()) { try { exportFile.getParentFile().mkdirs(); exportFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); logger.error("create local json file exception: " + e.getMessage()); return false; } } BufferedWriter bufferedWriter = null; try { FileOutputStream os = new FileOutputStream(exportFile); FileDescriptor fd = os.getFD(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); bufferedWriter.write(content); //Flush the data from the streams and writes into system buffers //The data may or may not be written to disk. bufferedWriter.flush(); //block until the system buffers have been written to disk. //After this method returns, the data is guaranteed to have //been written to disk. fd.sync(); } catch (UnsupportedEncodingException e) { logger.error("saveDBData#catch an UnsupportedEncodingException (" + e.getMessage() + ")"); return false; } catch (FileNotFoundException e) { logger.error("saveDBData#catch an FileNotFoundException (" + e.getMessage() + ")"); return false; } catch (IOException e) { logger.error("saveDBData#catch an IOException (" + e.getMessage() + ")"); return false; } catch (Exception e) { logger.error("saveDBData#catch an exception (" + e.getMessage() + ")"); return false; } finally { try { if (bufferedWriter != null) { bufferedWriter.close(); bufferedWriter = null; } } catch (IOException e) { logger.error("writeJsonToFile#catch an exception (" + e.getMessage() + ")"); } } return true; }
b.执行命令
public static boolean excuteCMDBatFile(String cmd) { final String METHOD_NAME = "excuteCMDBatFile#"; boolean result = true; Process p; File batFile = new File("D:/test/cmd.bat"); System.out.println(batFile.getAbsolutePath()); boolean isSuccess = FileUtils.writeFile(batFile, cmd); if(!isSuccess) { logger.error(METHOD_NAME + "write cmd to File failed."); return false; } String batFilePath = "\"" + MigrateContants.CMD_BAT_FILE + "\""; logger.info("cmd path:" + batFilePath); try { p = Runtime.getRuntime().exec(batFilePath); InputStream fis = p.getErrorStream();//p.getInputStream(); InputStreamReader isr = new InputStreamReader(fis, System.getProperty("file.encoding")); BufferedReader br = new BufferedReader(isr); String line = null; StringBuilder builder = new StringBuilder(); while ((line = br.readLine()) != null) { builder.append(line); } p.waitFor(); int i = p.exitValue(); logger.info(METHOD_NAME + "exitValue = " + i); if (i != 0) { result = false; logger.error(METHOD_NAME + "excute cmd failed, [result = " + result + ", error message = " + builder.toString() + "]"); System.out.println(METHOD_NAME + "excute cmd failed, [result = " + result + ", error message = " + builder.toString() + "]"); }else { // logger.debug(METHOD_NAME + "excute cmd result = " + result); System.out.println(METHOD_NAME + "result = " + result); } } catch (Exception e) { result = false; e.printStackTrace(); logger.error(METHOD_NAME + "fail to excute bat File [ErrMsg=" + e.getMessage() + "]"); } return result; }