java中执行cmd命令

一、java执行cmd命令的三种方式:http://www.jb51.net/article/80829.htm

参考:https://www.cnblogs.com/zhufu9426/p/7928570.htmlhttp://blog.csdn.net/Roy_70/article/details/51505314

二、cmd命令参考:https://baike.baidu.com/item/CMD%E5%91%BD%E4%BB%A4/9684689?fr=aladdin#3

方式一:

public static String checkPhysicalAddress() {
  String physicalAddress = "read MAC error!";  
  try {
   String line;
   Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
   BufferedReader bufferedReader = new BufferedReader(
     new InputStreamReader(process.getInputStream(),"gbk"));//使用gbk编码解决输出乱码问题
   while ((line = bufferedReader.readLine()) != null) {
    if (line.indexOf("Physical Address. . . . . . . . . :") != -1) {
     if (line.indexOf(":") != -1) {
      physicalAddress = line.substring(line.indexOf(":") + 2);
      break; // 找到MAC,退出循环
     }
    }
   }
   process.waitFor();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return physicalAddress;
 }

方式二:

public static void startProgram(String programPath) throws IOException { 
 log.info("启动应用程序:" + programPath); 
 if (StringUtils.isNotBlank(programPath)) { 
  try { 
   String programName = programPath.substring(programPath.lastIndexOf("/") + 1, programPath.lastIndexOf(".")); 
   List<String> list = new ArrayList<String>(); 
   list.add("cmd.exe"); 
   list.add("/c"); 
   list.add("start"); 
   list.add(""" + programName + """); 
   list.add(""" + programPath + """); 
   ProcessBuilder pBuilder = new ProcessBuilder(list); 
   pBuilder.start(); 
  } catch (Exception e) { 
   e.printStackTrace(); 
   log.error("应用程序:" + programPath + "不存在!"); 
  } 
 } 
} 

方式三:

public static void startProgram(String programPath) throws IOException { 
 log.info("启动应用程序:" + programPath); 
 if (StringUtils.isNotBlank(programPath)) { 
  try { 
   Desktop.getDesktop().open(new File(programPath)); 
  } catch (Exception e) { 
   e.printStackTrace(); 
   log.error("应用程序:" + programPath + "不存在!"); 
  } 
 } 
}

三、Java中使用Runtime和Process类运行外部程序

四、process中waitFor()问题

引用:JDK帮助文档上这么说:如有必要,一直要等到由该 Process 对象表示的进程已经终止。如果已终止该子进程,此方法立即返回。但是直接调用这个方法会导致当前线程阻塞,直到退出子进程。对此JDK文档上还有如此解释:因为本地的系统对标准输入和输出所提供的缓冲池有效,所以错误的对标准输出快速的写入何从标准输入快速的读入都有可能造成子进程的所,甚至死锁。好了,问题的关键在缓冲区这个地方:可执行程序的标准输出比较多,而运行窗口的标准缓冲区不够大,所以发生阻塞。接着来分析缓冲区,哪来的这个东西,当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitfor()这里。 知道问题所在,我们解决问题就好办了。查看网上说的方法多数是开两个线程在waitfor()命令之前读出窗口的标准输出缓冲区和标准错误流的内容。

  1.  p = Runtime.getRuntime().exec("notepad.exe");  
  2.  p.waitFor();  

总结:在方法 exec("notepad.exe");   调用的其它程序没有终止之前,p.waitFor()表示在此处等待,不继续执行后面的代码,类似于回调函数