博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java如何运行OS命令(转)
阅读量:7104 次
发布时间:2019-06-28

本文共 5444 字,大约阅读时间需要 18 分钟。

 

•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 fileProcess 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 blockednew 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中不能被获取到。

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

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

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

 修改后的代码

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

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

 

转载于:https://www.cnblogs.com/softidea/p/4267575.html

你可能感兴趣的文章
各种jar包下载地址
查看>>
HP P2000配置手册
查看>>
iOS视频教程【福利分享】
查看>>
SQL SERVER 数据类型 (转)
查看>>
linux工作常用命令
查看>>
博客系统 01 登录退出
查看>>
机试题
查看>>
客户端与服务器
查看>>
cookie
查看>>
Android Matrix
查看>>
JS实现OO机制
查看>>
约瑟夫问题
查看>>
python笔记第十天 模块
查看>>
自动办公系统
查看>>
asp.net mvc 3 unobtrusive client side validation not working in IE
查看>>
二.自动化接口测试---用例设计思路、模版
查看>>
svn项目冲突时显示无法加载项目的解决方法
查看>>
2019-4-22 jdbc学习笔记
查看>>
7 行代码优雅地实现 Excel 文件导出功能?
查看>>
thinkphp3.2.3 无法调用带下划线的模型
查看>>