java Runtime.exec方法详解
我们先来看看api的解释:
从字面上理解的意思就是在单独打开一条进程执行指定的命令。当然,这个方法有多个重载,如下:
下面会讲到其它的重载方法,不急。
想到api的解释我第一时间想到的就是cmd命令行!因为确实有些相似,但是转念一想又不对,“在单独的进程中执行指定的字符串命令”不就是这玩意儿吗!
然后我分别测试了这几个命令“explorer”,“calc”,“notepad”。都能正确的打开资源管理器、计算器和记事本程序。
但是cmd命令就不一样了,cmd命令不会弹出窗口,可能是以上几个命令是调用的外部的exe文件,而cmd不是吧,具体机制我不清楚,调用cmd命令呢在网上我看到了如下几种方法:
cmd /c dir 是执行完dir命令后关闭命令窗口。
cmd /k dir 是执行完dir命令后不关闭命令窗口。
cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。
cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。
/c start 和 /k start 我没测试过,主要使用的是/c,/k我测试了很多次,使用/k的话它怎么都获取不到输出的信息,无论是输入流还是错误输入流都不行!但是用/c就能正常获取,所以我一直使用的是/c。
然后,重点来了!划重点了!
谁说的调用一次exec方法不能执行多条cmd命令!
rt.exec("cmd /c set CLASSPATH=D:\\ && javac D:\\a.java && java a");
一个“&&”完美搞定~~
实测连接三条命令没问题,上限没测试过,各位看官无聊了可以去试试~~
但是,该方法有局限性,它只能在cmd里面使用,也就是前面必须有cmd三个字,你可以自己试试win+r调用cmd然后用&&连接多条命令执行,经过我的实测,是没有问题的,也就是说exec方法本质上还是只能调用一条命令的,我们能一次执行多条命令实际上是利用了cmd的语法的好处。
在上述代码中我先是设置了类路径为D盘根目录,完了编译a.java文件,紧接着运行a.class,在这里如果不设置classpath属性的话会导致运行a.class时报找不到类文件的错误。
可能大家已经觉得了,在上面的代码中我要设置classpath的属性又要javac一个完整的绝对路径,有没有什么方法能够一劳永逸呢?别说,还真有,这里就会用到其它几个重载的exec方法了。在这里我们只讲一个方法,因为其它的方法包括以上的那个方法最终都是调用它。
我们来一个参数一个参数的详解,第一个参数cmdarray——包含所调用命令极其参数的数组。
例如:shutdown -s -t 3600——在一小时后自动关机命令
我们可以构建这样的一个数组:String arr[] = {"shutdown","-s","-t","3600"};
数组第一个元素“shutdown”是命令,其后的三个-s、-t、3600都是参数,然后直接将这个数组注入exec方法即可。
需要注意的是,在调用这个方法时我们不能将命令和参数放在一起——String arr[] = {"shutdown -s -t 3600"};
这样去调用的话程序会把“shutdown -s -t 3600”当成是一条命令的名称,它会去查找“shutdown -s -t 3600”这条命令,它当然会找不到,所以就会报错,想要偷懒的话我们可以调用这个方法,我自己平时也是调用的这个方法,比较方便:
这个重载的方法会自动将一条字符串分解成命令和参数,最后再去调用我们现在讲解的这个方法。
然后是第二个参数:envp——字符串数组,其中每个元素的环境变量的设置格式为 name=value,如果子进程应该继承当前进程的环境,或该参数为null。
这个参数说白了就是去设置当前进程的环境变量,在上面的连接多条命令的例子中我们设置了classpath的路径,classpath其实就是一个环境变量,所以我们在这里就可以构建一个这样的数组:
String envp[] = {"CLASSPATH=D://"}
然后注入进exec方法即可,这样的话就可以直接java a去运行a.class了,程序会到D盘的根目录下去寻找a.class文件。
但是在我的测试中发现了一个很怪异的现象就是如果你在调用该方法的时候提供了这个参数,并且命令是cmd开头也就是在cmd中执行命令的时候,系统的环境变量就好像不存在了一样!你的环境变量就只剩下你数组提供的了。但是如果你不在cmd中执行命令,而是直接执行命令的话系统的环境变量又能发挥工作。
最后是第三个参数:dir——子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为 null。
其实就是设置当前的目录,一般要和cmd配合才能起作用,因为如果不在cmd里面执行命令的话,设置了目录也无济于事,程序依旧只会去环境变量设置的目录中寻找程序。
接下来我们就把上面的加粗的例子用这个方法调用:
String arr[] = {"CLASSPATH=D://","Path=C:\\Program Files\\Java\\jdk1.8.0_131\\bin"}; rt.exec("cmd /c javac a.java && java a", arr, new File("D://"));
在上述代码中我设置的环境变量数组使得命令能找到a.class和java这两个文件,因为第二个参数的怪异性,所以我这里还要设置java文件路径才能正常工作,最后设置的目录使得命令能找到a.java文件。
最后,大家应该注意到了,exec方法还有一个返回的对象Process,这个对象是给我们用来控制exec方法创建的进程的,该对象可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。 我将在下篇文章详细讲解Process类,我们下次再见~~拜拜~~
java Runtime.exec方法详解相关推荐
- Java之toString()方法详解
Java之toString()方法详解 Java中 toString()方法在Object类中和Intent类中都有定义,作用类似,但显示形式有点区别 一.Object类中toString()方法 t ...
- Java 静态工厂方法详解
Java 静态工厂方法详解 本文章主要是对<Effective Java>对静态工厂方法的理解 第一次使用静态工厂方法是在HIT<Software Construction>课 ...
- Java——多线程之方法详解
Java多线程系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多 ...
- js exec方法详解
今天查看jquery源码的时候突然被exec方法给弄懵了,特意翻了翻资料详细了解了下. 1.定义 exec() 方法用于检索字符串中的正则表达式的匹配. 使用方法:var match = RegExp ...
- javascript中match方法和exec()方法详解与深度区别(非原创)
match和exec的比较 1.match match方法属于String正则表达方法. 语法: str.match(regexp或者string) str:要进行匹配的字符串. regexp:一个 ...
- Java Arrays.asList()方法详解
本文是对Arrays.asList()方法从源码角度进行分析,解析使用中的一些困惑. 首先看Arrays.asList()的源码 public static <T> List<T&g ...
- java的intern()方法详解
尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作.在调用"ab".intern()方法的时候会返回"ab",但是这个 ...
- Java如何输入数据?Java数据输入方法详解!
在Java程序中输入数据是最基础的操作,但是如果你猜刚刚开始学习Java,大多数都会比较困惑,不知道怎么在Java中输入数据.甚至于很多程序员一开始还天真的以为它跟C和C++一样用scanf或cin, ...
- 【Java】equals() 方法详解
目录 equals 方法 equals方法重写 equals方法重写规则 equals方法比较String类型 Object 类中的 equals 方法用于检测一个对象是否等于另外一个对象 equal ...
- Java:join方法详解
文章目录 概念 原理 总结 代码案例:实现子线程先执行,主线程再执行 概念 Thread类提供了让一个线程等待另一个线程完成的方法--join()方法. 当在某个程序执行流中调用其他线程的join() ...
最新文章
- Datawhale赛事大满贯来了!
- python soket编程之一个ssh程序
- 临时表,临时表什么时候删除
- 在终端显示文本的中间部分
- Servlet中过滤器的实现原理(源码实现)
- 安卓牛客专项练习2020.12.31
- 你的不好意思,正在摧毁你
- XRD数据分析--如何使用Origin作图?
- 分析BarTender的SDK帮助文档
- 15款替代微软产品的开源软件
- Swift3.0学习笔记-Error Handling
- Windows使用CMD命令查看WIFI密码
- 配置SDN网关:关于VRF、本地路由及inet-vpn路由
- Cocos Creator转盘抽奖
- 三星优化器 适用于绝大部分安卓手机 超级好用!!
- 蓝桥杯大学JAVA题型_蓝桥杯 2020年省赛真题 10月第二场 (Java 大学B组)
- Exceptions In Java
- STM32WL开发之LORA开发环境及其Demo例程介绍
- 2022-07-10 第七小组 闫馨月 学习笔记
- Gradle多渠道打包(动态设定App名称,应用图标,替换常量,更改包名,变更渠道)