zoukankan      html  css  js  c++  java
  • java如何运行OS命令(转)

    •javac TestRunTime.java
    •java TestRunTime hostname // 执行“hostname”Linux命令
    •即可看到输出

    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.LineNumberReader;
    
    public class TestRunTime {
        public static void main(String[] args) throws IOException,
                InterruptedException {
            String cmd = "";
            if (args == null || args.length == 0) {
                System.out.println("请输入命令行参数");
            } else {
                for (int i = 0; i < args.length; i++) {
                    cmd += args[i] + " ";
                }
            }
            try {
                Process process = Runtime.getRuntime().exec(cmd);
                InputStreamReader ir = new InputStreamReader(
                        process.getInputStream());
                LineNumberReader input = new LineNumberReader(ir);
                String line;
                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (java.io.IOException e) {
                System.err.println("IOException " + e.getMessage());
            }
        }
    }

    http://www.cnblogs.com/alipayhutu/archive/2012/06/12/2546214.html



    命令执行不成功时,可以将标准错误流的信息打印出来,发现是bat文件的路径只获取到了第一个空格前。所以问题的原因是空格导致文件路径不能被获取。

    在正常情况下我们可以用Project.waitfor()的返回值是否等于0的方法来判断java调用外部程序是Pass或者是Fail。

    但是这个方法往往会被因进程堵塞而导致程序发生死锁,无法再继续执行外部程序。

    因为本地的系统对标准输入和输出所提供的缓冲池有限,所以错误的对标准输出快速的写入和从标准输入快速的读入都有可能造成子进程死锁。问题的关键在缓冲区这个地方:可执行程序的标准输出比较多,而运行窗口的标准缓冲区不够大,所以发生阻塞。接着来分析缓冲区,当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitfor()这里。

    但是在其中过程中真正起关键作用的缓冲区是getErrorStream()对应的那个缓冲区没有被清空,意思就是说其实只要及时读取标准错误流缓冲区的数据程序就不会被block。

    原先的代码

    //run bat file
    
     Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath.replaceAll(" ", "" ""));
    
     int exitcode=project.waitFor();
    
     //kill the process
    
         project.destroy();
    
                logger.info(exitcode);
    
                //if the exitcode is 0, the RIA TEST is passed,else the RIA TEST is failed    
    
                if(exitcode==0){
    
                logger.info("============ is Passed============");
    
                     }
    
                else{
    
                Boolean resultFlag=false;
    
                logger.info("============ is Failed============");
    
                Assert.assertTrue(bugID+"Failed",resultFlag);   
    
                }   

    修改后的代码:

    增加两个线程来读取标准输出流和标准错误流

    try{
    
    //run bat file
    
    Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath.replaceAll(" ", "" ""));
    
    final InputStream br = project.getInputStream();
    
    final InputStream br_error = project.getErrorStream();
    
    //run 2 threads to read the standard InputStream and the ErrorStream to avoid the project.
    
    //waitfor()method blocked
    new Thread() {  
             public void run() {  
                BufferedReader br1 = new BufferedReader(new InputStreamReader(br));  
                try {  
                 String line1 = null;  
                 while ((line1 = br1.readLine()) != null) {  
                          if (line1 != null){
                              logger.info("RIATest info: "+line1);
                          }  
                      }  
                } catch (IOException e) {  
                     e.printStackTrace();  
                }  
                 finally{  
                     try {  
                         br.close();  
                     } catch (IOException e) {  
                         e.printStackTrace();  
                    }  
                   }  
                }  
              }.start();  
    
    //run thread to read the standard ErrorStream
     new Thread() {  
             public void run() {  
                BufferedReader br2 = new BufferedReader(new InputStreamReader(br_error));  
                try {  
                 String line2 = null;  
                 while ((line2 = br2.readLine()) != null) {  
                          if (line2 != null){
                              logger.info("Error: "+line2);
                          }  
                      }  
                } catch (IOException e) {  
                     e.printStackTrace();  
                }  
                 finally{  
                     try {  
                         br_error.close();  
                     } catch (IOException e) {  
                         e.printStackTrace();  
                    }  
                   }  
                }  
    
              }.start();  
    try{ int exitcode=project.waitFor(); //kill the process project.destroy(); logger.info(exitcode); //if the exitcode is 0, the RIA TEST is passed,
    //else the RIA TEST is failed
        if(exitcode==0){
            logger.info("============ is Passed============");
        }
        else{
        Boolean resultFlag=false;
        logger.info("============ is Failed============");
        Assert.assertTrue(bugID+"Failed",resultFlag);   
        }   
    }
    catch(Throwable e){
        e.printStackTrace();
    }       
    }
    catch(IOException e){
        e.printStackTrace();
        try
        {
            project.getErrorStream().close();
            project.getInputStream().close();
            project.getOutputStream().close();  
        }
        catch(Exception ee){
    } }

    http://www.cnblogs.com/xriverside/p/4362609.html

    Java Runtime.getRuntime().exec() 执行带空格命令

    可执行文件路径如果包含空格,则在java中不能被获取到。

    此时Debug一下,会发现 project=null. project.waitFor 的返回值为1.但是去源路径单击bat文件是可以正常运行的,说明问题出在文件路径上。

    将文件路径中的空格用双引号引起来就可以了

    String batpath = file.getCanonicalPath() + "\resources\runTest.bat";
    //run bat file
    Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath);
    int exitcode=project.waitFor();
    //kill the process
    project.destroy();
    logger.info(exitcode);

     修改后的代码

    //run bat file
    Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath.replaceAll("[\d]{1,}", "" ""));

    http://www.cnblogs.com/xriverside/p/4362541.html

  • 相关阅读:
    如何在android 系统 C/C++ 层中添加 log 信息
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2拦截器的执行顺序
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2拦截方法的拦截器
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2实现拦截器类
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2实现文件下载的Action
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2拦截器实现文件过滤
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2手动实现文件过滤
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2实现文件上传的Action
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2手动完成输入校验(2)
    吴裕雄--天生自然轻量级JAVA EE企业应用开发Struts2Sping4Hibernate整合开发学习笔记:struts2手动完成输入校验
  • 原文地址:https://www.cnblogs.com/softidea/p/4267575.html
Copyright © 2011-2022 走看看