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;
    }
复制代码
posted @   话祥  阅读(24778)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示